replicas-cli 0.2.515 → 0.2.517
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 -248
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -8202,6 +8202,56 @@ var SANDBOX_PATHS = {
|
|
|
8202
8202
|
var WORKSPACE_SIZES = ["small", "large"];
|
|
8203
8203
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
8204
8204
|
|
|
8205
|
+
// ../shared/src/egress.ts
|
|
8206
|
+
var EGRESS_CIPHER = "aes-256-gcm";
|
|
8207
|
+
var EGRESS_SHADOWSOCKS_MODE = "tcp_and_udp";
|
|
8208
|
+
var EGRESS_SHADOWSOCKS_VERSION = "1.24.0";
|
|
8209
|
+
var EGRESS_SHADOWSOCKS_SHA256 = "0d84f5f350ec99396867d718f146fc3810975b2a7cd06192f158d96bdef460e7";
|
|
8210
|
+
var EGRESS_PORT_RANGE_START = 8400;
|
|
8211
|
+
var EGRESS_PORT_RANGE_END = 8499;
|
|
8212
|
+
var EGRESS_EXIT_IP_ENDPOINTS = [
|
|
8213
|
+
"https://checkip.amazonaws.com",
|
|
8214
|
+
"https://api.ipify.org",
|
|
8215
|
+
"https://icanhazip.com"
|
|
8216
|
+
];
|
|
8217
|
+
var EGRESS_DIRECT_ROUTES = [
|
|
8218
|
+
"10.0.0.0/8",
|
|
8219
|
+
"172.16.0.0/12",
|
|
8220
|
+
"192.168.0.0/16",
|
|
8221
|
+
"169.254.0.0/16",
|
|
8222
|
+
"100.64.0.0/10"
|
|
8223
|
+
];
|
|
8224
|
+
var EGRESS_SHELL_CONFIG = [
|
|
8225
|
+
`EGRESS_PORT_RANGE_START=${EGRESS_PORT_RANGE_START}`,
|
|
8226
|
+
`EGRESS_PORT_RANGE_END=${EGRESS_PORT_RANGE_END}`,
|
|
8227
|
+
`EGRESS_SHADOWSOCKS_VERSION=${EGRESS_SHADOWSOCKS_VERSION}`,
|
|
8228
|
+
`EGRESS_SHADOWSOCKS_SHA256=${EGRESS_SHADOWSOCKS_SHA256}`,
|
|
8229
|
+
`EGRESS_CIPHER=${EGRESS_CIPHER}`,
|
|
8230
|
+
`EGRESS_MODE=${EGRESS_SHADOWSOCKS_MODE}`,
|
|
8231
|
+
`EGRESS_EXIT_IP_ENDPOINTS="${EGRESS_EXIT_IP_ENDPOINTS.join(" ")}"`,
|
|
8232
|
+
`EGRESS_DIRECT_ROUTES="${EGRESS_DIRECT_ROUTES.join(" ")}"`
|
|
8233
|
+
].join("\n");
|
|
8234
|
+
var EGRESS_TUNNEL_SERVICE = "replicas-egress.service";
|
|
8235
|
+
var EGRESS_TUNNEL_INTERFACE = "rpxtun0";
|
|
8236
|
+
var EGRESS_DNS_SERVERS = ["1.1.1.1", "8.8.8.8"];
|
|
8237
|
+
var EGRESS_PATHS = {
|
|
8238
|
+
CONFIG_DIR: "/etc/replicas/egress",
|
|
8239
|
+
/** Root-only (0600). Holds the customer's proxy password — never baked into the image. */
|
|
8240
|
+
CONFIG_FILE: "/etc/replicas/egress/config.json",
|
|
8241
|
+
RESOLV_BACKUP: "/etc/replicas/egress/resolv.conf.orig",
|
|
8242
|
+
UNIT_FILE: `/etc/systemd/system/${EGRESS_TUNNEL_SERVICE}`,
|
|
8243
|
+
UP_SCRIPT: "/usr/local/lib/replicas-egress-up",
|
|
8244
|
+
DOWN_SCRIPT: "/usr/local/lib/replicas-egress-down"
|
|
8245
|
+
};
|
|
8246
|
+
var EGRESS_WORKSPACE_CONFIG_FILE = "/opt/replicas/egress-config.env";
|
|
8247
|
+
var EGRESS_WORKSPACE_SHELL_VARS = {
|
|
8248
|
+
EGRESS_WORKSPACE_CONFIG_FILE,
|
|
8249
|
+
EGRESS_TUNNEL_SERVICE,
|
|
8250
|
+
EGRESS_TUNNEL_INTERFACE,
|
|
8251
|
+
EGRESS_DNS_SERVERS: EGRESS_DNS_SERVERS.join(" "),
|
|
8252
|
+
EGRESS_EXIT_IP_ENDPOINTS: EGRESS_EXIT_IP_ENDPOINTS.join(" ")
|
|
8253
|
+
};
|
|
8254
|
+
|
|
8205
8255
|
// ../shared/src/urls.ts
|
|
8206
8256
|
var DEFAULT_WEB_APP_URL = "https://tryreplicas.com";
|
|
8207
8257
|
function getWorkspaceDashboardUrl(workspaceId, options = {}) {
|
|
@@ -8762,35 +8812,8 @@ var GITLAB_ABILITY = {
|
|
|
8762
8812
|
referenceFile: { name: "GITLAB.md", content: REFERENCE4 }
|
|
8763
8813
|
};
|
|
8764
8814
|
|
|
8765
|
-
// ../shared/src/default-skills/replicas-agent/abilities/learnings.ts
|
|
8766
|
-
var SECTION5 = `### Learnings
|
|
8767
|
-
Propose additions, updates, or deletions to curated organization knowledge.
|
|
8768
|
-
|
|
8769
|
-
**Reference:** \`references/LEARNINGS.md\``;
|
|
8770
|
-
var REFERENCE5 = `# Learnings
|
|
8771
|
-
|
|
8772
|
-
Learnings are curated, human-approved knowledge entries your organization maintains: conventions, gotchas, environment facts, and process rules.
|
|
8773
|
-
|
|
8774
|
-
All writes are proposals: a human reviews them in the dashboard, and nothing takes effect until approved.
|
|
8775
|
-
|
|
8776
|
-
Use \`replicas learnings --help\` and subcommand help such as \`replicas learnings add --help\`, \`replicas learnings update --help\`, or \`replicas learnings delete --help\` for current command syntax.
|
|
8777
|
-
|
|
8778
|
-
A human approves every proposal before it takes effect, so don't agonize over borderline calls \u2014 but keep proposals genuinely useful rather than reflexive.
|
|
8779
|
-
|
|
8780
|
-
- Propose \`add\` for anything repeatable and org-useful: user corrections and preferences, hard-won environment or process knowledge, conventions and decisions worth following, and gotchas that would waste time again. If you learned it the hard way this task, capture it.
|
|
8781
|
-
- Never store task-specific details that won't recur, facts trivially derivable by reading the repo, or secrets/credentials.
|
|
8782
|
-
- Propose \`update\` or \`delete\` when a learning is contradicted by the current code or docs, especially if the outdated guidance would affect future repeated work.
|
|
8783
|
-
- Write narrow triggers describing when the entry should surface (e.g. "UI/UX work on the admin panel"), not vague topics.`;
|
|
8784
|
-
var LEARNINGS_ABILITY = {
|
|
8785
|
-
label: "Learnings",
|
|
8786
|
-
description: "Propose changes to curated org knowledge for human review.",
|
|
8787
|
-
bullet: "- Proposing changes to organization Learnings (curated, human-approved knowledge)",
|
|
8788
|
-
section: SECTION5,
|
|
8789
|
-
referenceFile: { name: "LEARNINGS.md", content: REFERENCE5 }
|
|
8790
|
-
};
|
|
8791
|
-
|
|
8792
8815
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
8793
|
-
var
|
|
8816
|
+
var SECTION5 = `### Linear
|
|
8794
8817
|
Fetch issues, update state, add comments, and search through the workspace-scoped TypeScript SDK.
|
|
8795
8818
|
|
|
8796
8819
|
**Reference:** \`references/LINEAR.md\`
|
|
@@ -8799,7 +8822,7 @@ Use this when:
|
|
|
8799
8822
|
- You encounter a Linear issue link and need to understand the task
|
|
8800
8823
|
- You need to update an issue's state or add a comment
|
|
8801
8824
|
- You need to search Linear issues`;
|
|
8802
|
-
var
|
|
8825
|
+
var REFERENCE5 = `# Linear Integration
|
|
8803
8826
|
|
|
8804
8827
|
Use \`@replicas/sdk\`; never request or handle a Linear OAuth token. Replicas refreshes the organization credential behind the gateway.
|
|
8805
8828
|
|
|
@@ -8849,12 +8872,12 @@ var LINEAR_ABILITY = {
|
|
|
8849
8872
|
label: "Linear",
|
|
8850
8873
|
description: "Fetch issues, comment, and update state through @replicas/sdk.",
|
|
8851
8874
|
bullet: "- Interacting with Linear (fetching issues, updating state, commenting, etc.)",
|
|
8852
|
-
section:
|
|
8853
|
-
referenceFile: { name: "LINEAR.md", content:
|
|
8875
|
+
section: SECTION5,
|
|
8876
|
+
referenceFile: { name: "LINEAR.md", content: REFERENCE5 }
|
|
8854
8877
|
};
|
|
8855
8878
|
|
|
8856
8879
|
// ../shared/src/default-skills/replicas-agent/abilities/media.ts
|
|
8857
|
-
var
|
|
8880
|
+
var SECTION6 = `### Media
|
|
8858
8881
|
Share screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external messages.
|
|
8859
8882
|
|
|
8860
8883
|
**Reference:** \`references/MEDIA.md\`
|
|
@@ -8864,7 +8887,7 @@ Use this when:
|
|
|
8864
8887
|
- You produce a self-contained HTML report that should be linked from a pull request
|
|
8865
8888
|
- You record video output (browser automation, screen capture) \u2014 including the recommended aspect ratio and FPS
|
|
8866
8889
|
- You need to embed media in a Slack/Linear/GitHub message AND keep a referenceable copy in the Replicas dashboard`;
|
|
8867
|
-
var
|
|
8890
|
+
var REFERENCE6 = `# Media (Screenshots, Recordings, Audio, HTML)
|
|
8868
8891
|
|
|
8869
8892
|
This guide covers how to share screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external surfaces (Slack, Linear, GitHub).
|
|
8870
8893
|
|
|
@@ -9170,12 +9193,12 @@ var MEDIA_ABILITY = {
|
|
|
9170
9193
|
label: "Media",
|
|
9171
9194
|
description: "Share screenshots, recordings, generated images, audio clips, and HTML pages.",
|
|
9172
9195
|
bullet: "- Producing or showing the user any media \u2014 screenshots, screen recordings, generated images or diagrams, audio clips, or HTML recap pages \u2014 including in your Replicas chat reply, PR descriptions/comments, and other external platforms",
|
|
9173
|
-
section:
|
|
9174
|
-
referenceFile: { name: "MEDIA.md", content:
|
|
9196
|
+
section: SECTION6,
|
|
9197
|
+
referenceFile: { name: "MEDIA.md", content: REFERENCE6 }
|
|
9175
9198
|
};
|
|
9176
9199
|
|
|
9177
9200
|
// ../shared/src/default-skills/replicas-agent/abilities/previews.ts
|
|
9178
|
-
var
|
|
9201
|
+
var SECTION7 = `### Previews
|
|
9179
9202
|
Expose locally running services (web apps, APIs, databases) as public preview URLs so humans can interact with them directly.
|
|
9180
9203
|
|
|
9181
9204
|
**Reference:** \`references/PREVIEWS.md\`
|
|
@@ -9184,7 +9207,7 @@ Use this when:
|
|
|
9184
9207
|
- You need to start a service that a human should view or interact with
|
|
9185
9208
|
- The task involves UI work that benefits from human review
|
|
9186
9209
|
- You are verifying frontend/backend integrations visually`;
|
|
9187
|
-
var
|
|
9210
|
+
var REFERENCE7 = `# Preview URLs
|
|
9188
9211
|
|
|
9189
9212
|
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.
|
|
9190
9213
|
|
|
@@ -9260,12 +9283,12 @@ var PREVIEWS_ABILITY = {
|
|
|
9260
9283
|
label: "Previews",
|
|
9261
9284
|
description: "Expose locally running services on public preview URLs for humans.",
|
|
9262
9285
|
bullet: "- Creating preview URLs for locally running services",
|
|
9263
|
-
section:
|
|
9264
|
-
referenceFile: { name: "PREVIEWS.md", content:
|
|
9286
|
+
section: SECTION7,
|
|
9287
|
+
referenceFile: { name: "PREVIEWS.md", content: REFERENCE7 }
|
|
9265
9288
|
};
|
|
9266
9289
|
|
|
9267
9290
|
// ../shared/src/default-skills/replicas-agent/abilities/plugins.ts
|
|
9268
|
-
var
|
|
9291
|
+
var SECTION8 = `### Plugins
|
|
9269
9292
|
Discover and execute installed marketplace tools through the workspace-scoped TypeScript SDK.
|
|
9270
9293
|
|
|
9271
9294
|
**Reference:** \`references/PLUGINS.md\`
|
|
@@ -9280,7 +9303,7 @@ Use this when:
|
|
|
9280
9303
|
- The user asks for PlanetScale organizations, databases, branches, or Insights data
|
|
9281
9304
|
- The user asks to analyze text with Pangram
|
|
9282
9305
|
- The user asks for Stripe customers, payments, invoices, subscriptions, or balances`;
|
|
9283
|
-
var
|
|
9306
|
+
var REFERENCE8 = `# Plugins
|
|
9284
9307
|
|
|
9285
9308
|
Plugins are TypeScript libraries, not MCP servers. Import \`@replicas/sdk\`; Replicas authenticates the workspace and selects only the owner\u2019s personal connection or the organization fallback. Provider credentials, sessions, and project keys are never exposed.
|
|
9286
9309
|
|
|
@@ -9388,12 +9411,12 @@ var PLUGINS_ABILITY = {
|
|
|
9388
9411
|
label: "Plugins",
|
|
9389
9412
|
description: "Use installed marketplace tools through @replicas/sdk.",
|
|
9390
9413
|
bullet: "- Interacting with installed marketplace plugins through TypeScript",
|
|
9391
|
-
section:
|
|
9392
|
-
referenceFile: { name: "PLUGINS.md", content:
|
|
9414
|
+
section: SECTION8,
|
|
9415
|
+
referenceFile: { name: "PLUGINS.md", content: REFERENCE8 }
|
|
9393
9416
|
};
|
|
9394
9417
|
|
|
9395
9418
|
// ../shared/src/default-skills/replicas-agent/abilities/replicas.ts
|
|
9396
|
-
var
|
|
9419
|
+
var SECTION9 = `### Replicas (in-workspace CLI)
|
|
9397
9420
|
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.
|
|
9398
9421
|
|
|
9399
9422
|
**Reference:** \`references/REPLICAS.md\`
|
|
@@ -9404,7 +9427,7 @@ Use this when:
|
|
|
9404
9427
|
- The user asks "what envs / repos / automations do I have?"
|
|
9405
9428
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo
|
|
9406
9429
|
- You need to run a long-lived service (dev server, daemon) \u2014 always use \`replicas service start\` so it survives workspace sleep/wake`;
|
|
9407
|
-
var
|
|
9430
|
+
var REFERENCE9 = `# Replicas (in-workspace CLI)
|
|
9408
9431
|
|
|
9409
9432
|
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.
|
|
9410
9433
|
|
|
@@ -9631,13 +9654,13 @@ var REPLICAS_ABILITY = {
|
|
|
9631
9654
|
description: "Teach the agent about Replicas itself \u2014 automations, environments, the in-workspace CLI.",
|
|
9632
9655
|
// No bullet — help_instructions covers the `replicas` CLI surface in detail.
|
|
9633
9656
|
bullet: "",
|
|
9634
|
-
section:
|
|
9635
|
-
referenceFile: { name: "REPLICAS.md", content:
|
|
9657
|
+
section: SECTION9,
|
|
9658
|
+
referenceFile: { name: "REPLICAS.md", content: REFERENCE9 },
|
|
9636
9659
|
locked: true
|
|
9637
9660
|
};
|
|
9638
9661
|
|
|
9639
9662
|
// ../shared/src/default-skills/replicas-agent/abilities/sentry.ts
|
|
9640
|
-
var
|
|
9663
|
+
var SECTION10 = `### Sentry
|
|
9641
9664
|
Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
9642
9665
|
|
|
9643
9666
|
**Reference:** \`references/SENTRY.md\`
|
|
@@ -9645,7 +9668,7 @@ Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
|
9645
9668
|
Use this when:
|
|
9646
9669
|
- You need to inspect Sentry projects or issues
|
|
9647
9670
|
- A user asks for error-monitoring context outside a webhook-triggered task`;
|
|
9648
|
-
var
|
|
9671
|
+
var REFERENCE10 = `# Sentry Integration
|
|
9649
9672
|
|
|
9650
9673
|
Use \`@replicas/sdk\`; never request or read a Sentry token. Sentry access is organization-scoped and read-only.
|
|
9651
9674
|
|
|
@@ -9664,12 +9687,12 @@ var SENTRY_ABILITY = {
|
|
|
9664
9687
|
label: "Sentry",
|
|
9665
9688
|
description: "Read Sentry projects and issues through @replicas/sdk.",
|
|
9666
9689
|
bullet: "- Interacting with Sentry (reading projects, issues, and error context)",
|
|
9667
|
-
section:
|
|
9668
|
-
referenceFile: { name: "SENTRY.md", content:
|
|
9690
|
+
section: SECTION10,
|
|
9691
|
+
referenceFile: { name: "SENTRY.md", content: REFERENCE10 }
|
|
9669
9692
|
};
|
|
9670
9693
|
|
|
9671
9694
|
// ../shared/src/default-skills/replicas-agent/abilities/slack.ts
|
|
9672
|
-
var
|
|
9695
|
+
var SECTION11 = `### Slack
|
|
9673
9696
|
Send messages, read threads, search conversations, and upload files through the workspace-scoped TypeScript SDK.
|
|
9674
9697
|
|
|
9675
9698
|
**Reference:** \`references/SLACK.md\`
|
|
@@ -9678,7 +9701,7 @@ Use this when:
|
|
|
9678
9701
|
- You need to send a message to a Slack channel or thread
|
|
9679
9702
|
- You need to read or search Slack conversations
|
|
9680
9703
|
- You encounter a Slack message link and need its full thread`;
|
|
9681
|
-
var
|
|
9704
|
+
var REFERENCE11 = `# Slack Integration
|
|
9682
9705
|
|
|
9683
9706
|
Use \`@replicas/sdk\`; never read or send a Slack token directly. The SDK calls Replicas, which selects only this workspace's organization connection.
|
|
9684
9707
|
|
|
@@ -9751,8 +9774,8 @@ var SLACK_ABILITY = {
|
|
|
9751
9774
|
label: "Slack",
|
|
9752
9775
|
description: "Send messages, read threads, and search through @replicas/sdk.",
|
|
9753
9776
|
bullet: "- Interacting with Slack (sending messages, reading threads, etc.)",
|
|
9754
|
-
section:
|
|
9755
|
-
referenceFile: { name: "SLACK.md", content:
|
|
9777
|
+
section: SECTION11,
|
|
9778
|
+
referenceFile: { name: "SLACK.md", content: REFERENCE11 }
|
|
9756
9779
|
};
|
|
9757
9780
|
|
|
9758
9781
|
// ../shared/src/default-skills/replicas-agent/registry.ts
|
|
@@ -9762,7 +9785,6 @@ var REPLICAS_AGENT_ABILITY_REGISTRY = {
|
|
|
9762
9785
|
docker: DOCKER_ABILITY,
|
|
9763
9786
|
github: GITHUB_ABILITY,
|
|
9764
9787
|
gitlab: GITLAB_ABILITY,
|
|
9765
|
-
learnings: LEARNINGS_ABILITY,
|
|
9766
9788
|
linear: LINEAR_ABILITY,
|
|
9767
9789
|
media: MEDIA_ABILITY,
|
|
9768
9790
|
plugins: PLUGINS_ABILITY,
|
|
@@ -9868,7 +9890,7 @@ function formatTurnElapsed(ms) {
|
|
|
9868
9890
|
}
|
|
9869
9891
|
|
|
9870
9892
|
// ../shared/src/cli-version.ts
|
|
9871
|
-
var CLI_VERSION = "0.2.
|
|
9893
|
+
var CLI_VERSION = "0.2.517";
|
|
9872
9894
|
|
|
9873
9895
|
// ../shared/src/version.ts
|
|
9874
9896
|
function compareVersions(v1, v2) {
|
|
@@ -24598,7 +24620,8 @@ var workspaceChangedEventSchema = external_exports.discriminatedUnion("type", [
|
|
|
24598
24620
|
workspaceId: external_exports.string(),
|
|
24599
24621
|
completion: external_exports.object({
|
|
24600
24622
|
workspaceName: external_exports.string(),
|
|
24601
|
-
completedAt: external_exports.string()
|
|
24623
|
+
completedAt: external_exports.string(),
|
|
24624
|
+
processing: external_exports.boolean().optional()
|
|
24602
24625
|
}).optional(),
|
|
24603
24626
|
ts: external_exports.string()
|
|
24604
24627
|
}),
|
|
@@ -30688,134 +30711,6 @@ async function serviceLogsCommand(name, options) {
|
|
|
30688
30711
|
console.log(logs || "(no log output yet)");
|
|
30689
30712
|
}
|
|
30690
30713
|
|
|
30691
|
-
// src/commands/learnings.ts
|
|
30692
|
-
import { createHash as createHash2 } from "crypto";
|
|
30693
|
-
import { mkdirSync as mkdirSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, statSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
30694
|
-
import { join as join2 } from "path";
|
|
30695
|
-
var SESSIONS_DIR = join2(CONFIG_DIR, "learnings-sessions");
|
|
30696
|
-
var REPRINT_AFTER_READS = 50;
|
|
30697
|
-
var SESSION_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
30698
|
-
function sessionFilePath() {
|
|
30699
|
-
const key = process.env.REPLICAS_CHAT_ID || process.env.CLAUDE_CODE_SESSION_ID;
|
|
30700
|
-
return key ? join2(SESSIONS_DIR, `${key.replace(/[^a-zA-Z0-9_-]/g, "-")}.json`) : null;
|
|
30701
|
-
}
|
|
30702
|
-
function readSession(path6) {
|
|
30703
|
-
const session = { reads: 0, shown: {} };
|
|
30704
|
-
try {
|
|
30705
|
-
const parsed = JSON.parse(readFileSync2(path6, "utf-8"));
|
|
30706
|
-
if (typeof parsed?.reads === "number") session.reads = parsed.reads;
|
|
30707
|
-
const shown = parsed?.shown ?? {};
|
|
30708
|
-
for (const [id, entry] of Object.entries(shown)) {
|
|
30709
|
-
if (typeof entry?.read === "number" && typeof entry?.hash === "string") {
|
|
30710
|
-
session.shown[id] = { read: entry.read, hash: entry.hash };
|
|
30711
|
-
}
|
|
30712
|
-
}
|
|
30713
|
-
} catch {
|
|
30714
|
-
}
|
|
30715
|
-
return session;
|
|
30716
|
-
}
|
|
30717
|
-
function writeSession(path6, session) {
|
|
30718
|
-
try {
|
|
30719
|
-
mkdirSync2(SESSIONS_DIR, { recursive: true, mode: 448 });
|
|
30720
|
-
writeFileSync2(path6, JSON.stringify(session), { mode: 384 });
|
|
30721
|
-
for (const entry of readdirSync2(SESSIONS_DIR)) {
|
|
30722
|
-
const file2 = join2(SESSIONS_DIR, entry);
|
|
30723
|
-
if (Date.now() - statSync(file2).mtimeMs > SESSION_TTL_MS) unlinkSync(file2);
|
|
30724
|
-
}
|
|
30725
|
-
} catch {
|
|
30726
|
-
}
|
|
30727
|
-
}
|
|
30728
|
-
function printBlocks(learnings) {
|
|
30729
|
-
for (const learning of learnings) {
|
|
30730
|
-
const labels = [
|
|
30731
|
-
learning.scope === "global" ? "org-wide" : "environment",
|
|
30732
|
-
...learning.always_apply ? ["always applies"] : []
|
|
30733
|
-
];
|
|
30734
|
-
console.log(`## ${learning.name} (id: ${learning.id}, ${labels.join(", ")})`);
|
|
30735
|
-
console.log(learning.content);
|
|
30736
|
-
console.log("");
|
|
30737
|
-
}
|
|
30738
|
-
}
|
|
30739
|
-
async function learningsReadCommand(options) {
|
|
30740
|
-
const query = options.query?.trim();
|
|
30741
|
-
if (!query) {
|
|
30742
|
-
throw new Error("--query is required. Enrich it with codebase specifics (feature area, module names).");
|
|
30743
|
-
}
|
|
30744
|
-
const response = await agentFetch("/v1/agent/learnings/read", {
|
|
30745
|
-
method: "POST",
|
|
30746
|
-
body: { query }
|
|
30747
|
-
});
|
|
30748
|
-
const path6 = sessionFilePath();
|
|
30749
|
-
const session = path6 ? readSession(path6) : null;
|
|
30750
|
-
if (session) session.reads += 1;
|
|
30751
|
-
const unseen = response.learnings.filter((learning) => {
|
|
30752
|
-
if (!session) return true;
|
|
30753
|
-
const hash2 = createHash2("sha256").update(learning.content).digest("hex").slice(0, 16);
|
|
30754
|
-
const shown = session.shown[learning.id];
|
|
30755
|
-
if (!options.fresh && shown && shown.hash === hash2 && session.reads - shown.read < REPRINT_AFTER_READS) {
|
|
30756
|
-
return false;
|
|
30757
|
-
}
|
|
30758
|
-
session.shown[learning.id] = { read: session.reads, hash: hash2 };
|
|
30759
|
-
return true;
|
|
30760
|
-
});
|
|
30761
|
-
if (response.learnings.length === 0) {
|
|
30762
|
-
console.log("No learnings matched this query.");
|
|
30763
|
-
} else if (unseen.length === 0) {
|
|
30764
|
-
console.log("No new learnings \u2014 the matching ones were already shown earlier in this session.");
|
|
30765
|
-
} else {
|
|
30766
|
-
printBlocks(unseen);
|
|
30767
|
-
}
|
|
30768
|
-
if (response.matching_degraded) {
|
|
30769
|
-
console.log("Note: trigger matching was unavailable \u2014 only always-apply learnings are shown.");
|
|
30770
|
-
}
|
|
30771
|
-
if (path6 && session) writeSession(path6, session);
|
|
30772
|
-
}
|
|
30773
|
-
async function propose(request) {
|
|
30774
|
-
const { proposal } = await agentFetch("/v1/agent/learnings/proposals", {
|
|
30775
|
-
method: "POST",
|
|
30776
|
-
body: request
|
|
30777
|
-
});
|
|
30778
|
-
console.log(
|
|
30779
|
-
`Proposal submitted for human review (${proposal.action}, id: ${proposal.id}). It only takes effect once approved in the dashboard.`
|
|
30780
|
-
);
|
|
30781
|
-
}
|
|
30782
|
-
async function learningsAddCommand(options) {
|
|
30783
|
-
await propose({
|
|
30784
|
-
action: "add",
|
|
30785
|
-
name: options.name,
|
|
30786
|
-
content: options.content,
|
|
30787
|
-
trigger: options.trigger,
|
|
30788
|
-
always_apply: options.always || void 0,
|
|
30789
|
-
global: options.global || void 0
|
|
30790
|
-
});
|
|
30791
|
-
}
|
|
30792
|
-
function parseAlways(value) {
|
|
30793
|
-
if (value === void 0) return void 0;
|
|
30794
|
-
if (value !== "true" && value !== "false") {
|
|
30795
|
-
throw new Error("--always must be 'true' or 'false'");
|
|
30796
|
-
}
|
|
30797
|
-
return value === "true";
|
|
30798
|
-
}
|
|
30799
|
-
async function learningsUpdateCommand(id, options) {
|
|
30800
|
-
await propose({
|
|
30801
|
-
action: "update",
|
|
30802
|
-
target_learning_id: id,
|
|
30803
|
-
name: options.name,
|
|
30804
|
-
content: options.content,
|
|
30805
|
-
trigger: options.trigger,
|
|
30806
|
-
always_apply: parseAlways(options.always)
|
|
30807
|
-
});
|
|
30808
|
-
}
|
|
30809
|
-
async function learningsDeleteCommand(id) {
|
|
30810
|
-
await propose({ action: "delete", target_learning_id: id });
|
|
30811
|
-
}
|
|
30812
|
-
async function learningsWithdrawCommand(id) {
|
|
30813
|
-
const { proposal } = await agentFetch(`/v1/agent/learnings/proposals/${id}/withdraw`, {
|
|
30814
|
-
method: "POST"
|
|
30815
|
-
});
|
|
30816
|
-
console.log(`Proposal withdrawn (id: ${proposal.id}).`);
|
|
30817
|
-
}
|
|
30818
|
-
|
|
30819
30714
|
// src/commands/mothership.ts
|
|
30820
30715
|
async function mothershipSpawnCommand(options) {
|
|
30821
30716
|
const channel = options.channel?.trim();
|
|
@@ -35427,67 +35322,6 @@ if (isAgentMode()) {
|
|
|
35427
35322
|
if (error51 instanceof Error) {
|
|
35428
35323
|
console.error(chalk23.red(`
|
|
35429
35324
|
\u2717 ${error51.message}
|
|
35430
|
-
`));
|
|
35431
|
-
}
|
|
35432
|
-
process.exit(1);
|
|
35433
|
-
}
|
|
35434
|
-
});
|
|
35435
|
-
const learnings = program.command("learnings").description("Fetch curated org knowledge and propose changes for human review");
|
|
35436
|
-
learnings.command("read").description("Fetch learnings relevant to a task. Enrich the query with codebase specifics, not the raw user request.").requiredOption("-q, --query <query>", "Enriched task description to match against learning triggers").option("-f, --fresh", "Print full text even for learnings already shown in this session").action(async (options) => {
|
|
35437
|
-
try {
|
|
35438
|
-
await learningsReadCommand(options);
|
|
35439
|
-
} catch (error51) {
|
|
35440
|
-
if (error51 instanceof Error) {
|
|
35441
|
-
console.error(chalk23.red(`
|
|
35442
|
-
\u2717 ${error51.message}
|
|
35443
|
-
`));
|
|
35444
|
-
}
|
|
35445
|
-
process.exit(1);
|
|
35446
|
-
}
|
|
35447
|
-
});
|
|
35448
|
-
learnings.command("add").description("Propose a new learning (pending human review)").requiredOption("-n, --name <name>", "Short name for the learning").requiredOption("-c, --content <content>", "The knowledge itself").option("-t, --trigger <trigger>", "When this learning should surface (required unless --always)").option("-a, --always", "Always apply instead of trigger-matching").option("-g, --global", "Propose org-wide scope instead of this workspace environment").action(async (options) => {
|
|
35449
|
-
try {
|
|
35450
|
-
await learningsAddCommand(options);
|
|
35451
|
-
} catch (error51) {
|
|
35452
|
-
if (error51 instanceof Error) {
|
|
35453
|
-
console.error(chalk23.red(`
|
|
35454
|
-
\u2717 ${error51.message}
|
|
35455
|
-
`));
|
|
35456
|
-
}
|
|
35457
|
-
process.exit(1);
|
|
35458
|
-
}
|
|
35459
|
-
});
|
|
35460
|
-
learnings.command("update <id>").description("Propose changes to an existing learning (pending human review)").option("-n, --name <name>", "New name").option("-c, --content <content>", "New content").option("-t, --trigger <trigger>", "New trigger").option("-a, --always <bool>", "Set always-apply: 'true' or 'false'").action(async (id, options) => {
|
|
35461
|
-
try {
|
|
35462
|
-
await learningsUpdateCommand(id, options);
|
|
35463
|
-
} catch (error51) {
|
|
35464
|
-
if (error51 instanceof Error) {
|
|
35465
|
-
console.error(chalk23.red(`
|
|
35466
|
-
\u2717 ${error51.message}
|
|
35467
|
-
`));
|
|
35468
|
-
}
|
|
35469
|
-
process.exit(1);
|
|
35470
|
-
}
|
|
35471
|
-
});
|
|
35472
|
-
learnings.command("delete <id>").description("Propose deleting an outdated learning (pending human review)").action(async (id) => {
|
|
35473
|
-
try {
|
|
35474
|
-
await learningsDeleteCommand(id);
|
|
35475
|
-
} catch (error51) {
|
|
35476
|
-
if (error51 instanceof Error) {
|
|
35477
|
-
console.error(chalk23.red(`
|
|
35478
|
-
\u2717 ${error51.message}
|
|
35479
|
-
`));
|
|
35480
|
-
}
|
|
35481
|
-
process.exit(1);
|
|
35482
|
-
}
|
|
35483
|
-
});
|
|
35484
|
-
learnings.command("withdraw <id>").description("Withdraw a pending learning proposal from this workspace").action(async (id) => {
|
|
35485
|
-
try {
|
|
35486
|
-
await learningsWithdrawCommand(id);
|
|
35487
|
-
} catch (error51) {
|
|
35488
|
-
if (error51 instanceof Error) {
|
|
35489
|
-
console.error(chalk23.red(`
|
|
35490
|
-
\u2717 ${error51.message}
|
|
35491
35325
|
`));
|
|
35492
35326
|
}
|
|
35493
35327
|
process.exit(1);
|
|
@@ -35532,7 +35366,6 @@ if (isAgentMode()) {
|
|
|
35532
35366
|
"automation",
|
|
35533
35367
|
"repos",
|
|
35534
35368
|
"environment",
|
|
35535
|
-
"learnings",
|
|
35536
35369
|
"mothership"
|
|
35537
35370
|
]);
|
|
35538
35371
|
const kept = program.commands.filter((cmd) => allowed.has(cmd.name()));
|