@askexenow/exe-os 0.9.39 → 0.9.41
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/bin/backfill-conversations.js +7 -1
- package/dist/bin/backfill-responses.js +7 -1
- package/dist/bin/backfill-vectors.js +7 -1
- package/dist/bin/cleanup-stale-review-tasks.js +7 -1
- package/dist/bin/cli.js +43 -4
- package/dist/bin/exe-agent.js +7 -1
- package/dist/bin/exe-assign.js +7 -1
- package/dist/bin/exe-boot.js +7 -1
- package/dist/bin/exe-call.js +7 -1
- package/dist/bin/exe-dispatch.js +7 -1
- package/dist/bin/exe-doctor.js +7 -1
- package/dist/bin/exe-export-behaviors.js +7 -1
- package/dist/bin/exe-forget.js +7 -1
- package/dist/bin/exe-gateway.js +7 -1
- package/dist/bin/exe-heartbeat.js +7 -1
- package/dist/bin/exe-kill.js +7 -1
- package/dist/bin/exe-launch-agent.js +7 -1
- package/dist/bin/exe-new-employee.js +7 -1
- package/dist/bin/exe-pending-messages.js +7 -1
- package/dist/bin/exe-pending-notifications.js +7 -1
- package/dist/bin/exe-pending-reviews.js +7 -1
- package/dist/bin/exe-rename.js +7 -1
- package/dist/bin/exe-review.js +7 -1
- package/dist/bin/exe-search.js +7 -1
- package/dist/bin/exe-session-cleanup.js +7 -1
- package/dist/bin/exe-start-codex.js +7 -1
- package/dist/bin/exe-start-opencode.js +7 -1
- package/dist/bin/exe-status.js +7 -1
- package/dist/bin/exe-team.js +7 -1
- package/dist/bin/git-sweep.js +7 -1
- package/dist/bin/graph-backfill.js +7 -1
- package/dist/bin/graph-export.js +7 -1
- package/dist/bin/intercom-check.js +7 -1
- package/dist/bin/scan-tasks.js +7 -1
- package/dist/bin/setup.js +7 -1
- package/dist/bin/shard-migrate.js +7 -1
- package/dist/bin/update.js +36 -3
- package/dist/gateway/index.js +7 -1
- package/dist/hooks/bug-report-worker.js +7 -1
- package/dist/hooks/codex-stop-task-finalizer.js +7 -1
- package/dist/hooks/commit-complete.js +7 -1
- package/dist/hooks/error-recall.js +7 -1
- package/dist/hooks/ingest.js +7 -1
- package/dist/hooks/instructions-loaded.js +7 -1
- package/dist/hooks/notification.js +7 -1
- package/dist/hooks/post-compact.js +7 -1
- package/dist/hooks/post-tool-combined.js +7 -1
- package/dist/hooks/pre-compact.js +7 -1
- package/dist/hooks/pre-tool-use.js +7 -1
- package/dist/hooks/prompt-submit.js +7 -1
- package/dist/hooks/session-end.js +7 -1
- package/dist/hooks/session-start.js +7 -1
- package/dist/hooks/stop.js +7 -1
- package/dist/hooks/subagent-stop.js +7 -1
- package/dist/hooks/summary-worker.js +7 -1
- package/dist/index.js +7 -1
- package/dist/lib/employee-templates.js +7 -1
- package/dist/lib/exe-daemon.js +276 -47
- package/dist/lib/hybrid-search.js +7 -1
- package/dist/lib/schedules.js +7 -1
- package/dist/lib/store.js +7 -1
- package/dist/mcp/server.js +251 -29
- package/dist/runtime/index.js +7 -1
- package/dist/tui/App.js +7 -1
- package/package.json +2 -2
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -4088,7 +4088,7 @@ async function tryKeytar() {
|
|
|
4088
4088
|
}
|
|
4089
4089
|
function deriveMachineKey() {
|
|
4090
4090
|
try {
|
|
4091
|
-
const
|
|
4091
|
+
const crypto22 = __require("crypto");
|
|
4092
4092
|
const material = [
|
|
4093
4093
|
os6.hostname(),
|
|
4094
4094
|
os6.userInfo().username,
|
|
@@ -4097,7 +4097,7 @@ function deriveMachineKey() {
|
|
|
4097
4097
|
// Machine ID on Linux (stable across reboots)
|
|
4098
4098
|
process.platform === "linux" ? readMachineId() : ""
|
|
4099
4099
|
].join("|");
|
|
4100
|
-
return
|
|
4100
|
+
return crypto22.createHash("sha256").update(material).digest();
|
|
4101
4101
|
} catch {
|
|
4102
4102
|
return null;
|
|
4103
4103
|
}
|
|
@@ -4111,9 +4111,9 @@ function readMachineId() {
|
|
|
4111
4111
|
}
|
|
4112
4112
|
}
|
|
4113
4113
|
function encryptWithMachineKey(plaintext, machineKey) {
|
|
4114
|
-
const
|
|
4115
|
-
const iv =
|
|
4116
|
-
const cipher =
|
|
4114
|
+
const crypto22 = __require("crypto");
|
|
4115
|
+
const iv = crypto22.randomBytes(12);
|
|
4116
|
+
const cipher = crypto22.createCipheriv("aes-256-gcm", machineKey, iv);
|
|
4117
4117
|
let encrypted = cipher.update(plaintext, "utf-8", "base64");
|
|
4118
4118
|
encrypted += cipher.final("base64");
|
|
4119
4119
|
const authTag = cipher.getAuthTag().toString("base64");
|
|
@@ -4122,13 +4122,13 @@ function encryptWithMachineKey(plaintext, machineKey) {
|
|
|
4122
4122
|
function decryptWithMachineKey(encrypted, machineKey) {
|
|
4123
4123
|
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
4124
4124
|
try {
|
|
4125
|
-
const
|
|
4125
|
+
const crypto22 = __require("crypto");
|
|
4126
4126
|
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
4127
4127
|
if (parts.length !== 3) return null;
|
|
4128
4128
|
const [ivB64, tagB64, cipherB64] = parts;
|
|
4129
4129
|
const iv = Buffer.from(ivB64, "base64");
|
|
4130
4130
|
const authTag = Buffer.from(tagB64, "base64");
|
|
4131
|
-
const decipher =
|
|
4131
|
+
const decipher = crypto22.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
4132
4132
|
decipher.setAuthTag(authTag);
|
|
4133
4133
|
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
4134
4134
|
decrypted += decipher.final("utf-8");
|
|
@@ -4408,6 +4408,12 @@ var init_platform_procedures = __esm({
|
|
|
4408
4408
|
priority: "p0",
|
|
4409
4409
|
content: "NEVER: (1) Access the database directly \u2014 it's SQLCipher encrypted, always fails. Use MCP tools only. (2) Manually spawn tmux sessions \u2014 create_task handles it. (3) Run git checkout main \u2014 agents work in worktrees. (4) Modify another agent's in-progress task. (5) Push to remote \u2014 the COO reviews and pushes. (6) Skip update_task(done) \u2014 it's the ONLY way your work gets reviewed. (7) Run git init."
|
|
4410
4410
|
},
|
|
4411
|
+
{
|
|
4412
|
+
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
4413
|
+
domain: "support",
|
|
4414
|
+
priority: "p0",
|
|
4415
|
+
content: "Before editing platform code for a customer issue, classify it. Upstream bug = reproducible exe-os/platform defect; call create_bug_report with repro/version/workaround and avoid permanent local patches unless founder approves. Customer customization = identity, behavior, procedure, config, branding, workflow; store it in customer-owned layers, not platform code. Emergency hotfix = temporary only; document files/diff and re-check after npm update."
|
|
4416
|
+
},
|
|
4411
4417
|
// --- Operations ---
|
|
4412
4418
|
{
|
|
4413
4419
|
title: "Managers must supervise deployed workers",
|
|
@@ -4476,7 +4482,7 @@ var init_platform_procedures = __esm({
|
|
|
4476
4482
|
title: "MCP tools \u2014 identity, behavior, and decisions",
|
|
4477
4483
|
domain: "tool-use",
|
|
4478
4484
|
priority: "p1",
|
|
4479
|
-
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query."
|
|
4485
|
+
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query. create_bug_report: classify/file upstream bugs, customer customizations, and emergency hotfixes."
|
|
4480
4486
|
},
|
|
4481
4487
|
{
|
|
4482
4488
|
title: "MCP tools \u2014 communication and messaging",
|
|
@@ -5602,8 +5608,8 @@ async function embedDirect(text3) {
|
|
|
5602
5608
|
const llamaCpp = await import("node-llama-cpp");
|
|
5603
5609
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
5604
5610
|
const { existsSync: existsSync40 } = await import("fs");
|
|
5605
|
-
const
|
|
5606
|
-
const modelPath =
|
|
5611
|
+
const path54 = await import("path");
|
|
5612
|
+
const modelPath = path54.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
5607
5613
|
if (!existsSync40(modelPath)) {
|
|
5608
5614
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
5609
5615
|
}
|
|
@@ -6681,10 +6687,10 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6681
6687
|
};
|
|
6682
6688
|
try {
|
|
6683
6689
|
const fs = await import("fs");
|
|
6684
|
-
const
|
|
6690
|
+
const path54 = await import("path");
|
|
6685
6691
|
const os23 = await import("os");
|
|
6686
|
-
const logPath =
|
|
6687
|
-
fs.mkdirSync(
|
|
6692
|
+
const logPath = path54.join(os23.homedir(), ".exe-os", "search-quality.jsonl");
|
|
6693
|
+
fs.mkdirSync(path54.dirname(logPath), { recursive: true });
|
|
6688
6694
|
fs.appendFileSync(logPath, JSON.stringify(logEntry) + "\n");
|
|
6689
6695
|
} catch {
|
|
6690
6696
|
}
|
|
@@ -8302,8 +8308,8 @@ __export(wiki_client_exports, {
|
|
|
8302
8308
|
listDocuments: () => listDocuments,
|
|
8303
8309
|
listWorkspaces: () => listWorkspaces
|
|
8304
8310
|
});
|
|
8305
|
-
async function wikiFetch(config2,
|
|
8306
|
-
const url = `${config2.baseUrl}/api/v1${
|
|
8311
|
+
async function wikiFetch(config2, path54, method = "GET", body) {
|
|
8312
|
+
const url = `${config2.baseUrl}/api/v1${path54}`;
|
|
8307
8313
|
const headers = {
|
|
8308
8314
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
8309
8315
|
"Content-Type": "application/json"
|
|
@@ -8336,7 +8342,7 @@ async function wikiFetch(config2, path53, method = "GET", body) {
|
|
|
8336
8342
|
}
|
|
8337
8343
|
}
|
|
8338
8344
|
if (!response.ok) {
|
|
8339
|
-
throw new Error(`Wiki API ${method} ${
|
|
8345
|
+
throw new Error(`Wiki API ${method} ${path54}: ${response.status} ${response.statusText}`);
|
|
8340
8346
|
}
|
|
8341
8347
|
return response.json();
|
|
8342
8348
|
} finally {
|
|
@@ -18747,9 +18753,9 @@ var init_hostinger_api = __esm({
|
|
|
18747
18753
|
}
|
|
18748
18754
|
this.lastRequestTime = Date.now();
|
|
18749
18755
|
}
|
|
18750
|
-
async request(method,
|
|
18756
|
+
async request(method, path54, body) {
|
|
18751
18757
|
await this.rateLimit();
|
|
18752
|
-
const url = `${this.baseUrl}${
|
|
18758
|
+
const url = `${this.baseUrl}${path54}`;
|
|
18753
18759
|
const headers = {
|
|
18754
18760
|
Authorization: `Bearer ${this.apiKey}`,
|
|
18755
18761
|
"Content-Type": "application/json",
|
|
@@ -18818,8 +18824,8 @@ async function requestCloudflare(cfApiToken, zoneId, options) {
|
|
|
18818
18824
|
}
|
|
18819
18825
|
return envelope.result;
|
|
18820
18826
|
}
|
|
18821
|
-
function buildUrl(zoneId,
|
|
18822
|
-
const normalizedPath =
|
|
18827
|
+
function buildUrl(zoneId, path54 = "/dns_records", query) {
|
|
18828
|
+
const normalizedPath = path54.startsWith("/") ? path54 : `/${path54}`;
|
|
18823
18829
|
const url = new URL(
|
|
18824
18830
|
`${CLOUDFLARE_API_BASE_URL}/zones/${zoneId}${normalizedPath}`
|
|
18825
18831
|
);
|
|
@@ -21146,12 +21152,12 @@ function registerExportGraph(server) {
|
|
|
21146
21152
|
}
|
|
21147
21153
|
const html = await exportGraphHTML(client);
|
|
21148
21154
|
const fs = await import("fs");
|
|
21149
|
-
const
|
|
21155
|
+
const path54 = await import("path");
|
|
21150
21156
|
const os23 = await import("os");
|
|
21151
|
-
const outDir =
|
|
21157
|
+
const outDir = path54.join(os23.homedir(), ".exe-os", "exports");
|
|
21152
21158
|
fs.mkdirSync(outDir, { recursive: true });
|
|
21153
21159
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
21154
|
-
const filePath =
|
|
21160
|
+
const filePath = path54.join(outDir, `graph-${timestamp}.html`);
|
|
21155
21161
|
fs.writeFileSync(filePath, html, "utf-8");
|
|
21156
21162
|
return {
|
|
21157
21163
|
content: [
|
|
@@ -26794,6 +26800,225 @@ var init_activate_license = __esm({
|
|
|
26794
26800
|
}
|
|
26795
26801
|
});
|
|
26796
26802
|
|
|
26803
|
+
// src/mcp/tools/create-bug-report.ts
|
|
26804
|
+
import { z as z82 } from "zod";
|
|
26805
|
+
import crypto19 from "crypto";
|
|
26806
|
+
import { mkdir as mkdir6, writeFile as writeFile7 } from "fs/promises";
|
|
26807
|
+
import path49 from "path";
|
|
26808
|
+
function slugify2(input) {
|
|
26809
|
+
return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "bug-report";
|
|
26810
|
+
}
|
|
26811
|
+
function formatList(items) {
|
|
26812
|
+
if (!items || items.length === 0) return "- Not provided";
|
|
26813
|
+
return items.map((item) => `- ${item}`).join("\n");
|
|
26814
|
+
}
|
|
26815
|
+
function section(title, body) {
|
|
26816
|
+
return `## ${title}
|
|
26817
|
+
|
|
26818
|
+
${body?.trim() || "Not provided"}`;
|
|
26819
|
+
}
|
|
26820
|
+
function buildMarkdown(input) {
|
|
26821
|
+
return [
|
|
26822
|
+
`# Bug Report \u2014 ${input.title}`,
|
|
26823
|
+
"",
|
|
26824
|
+
`id: ${input.id}`,
|
|
26825
|
+
`classification: ${input.classification}`,
|
|
26826
|
+
`severity: ${input.severity}`,
|
|
26827
|
+
`filed_by: ${input.agentId} (${input.agentRole})`,
|
|
26828
|
+
`package_version: ${input.packageVersion}`,
|
|
26829
|
+
`project: ${input.projectName ?? "unknown"}`,
|
|
26830
|
+
`created_at: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
26831
|
+
"",
|
|
26832
|
+
section("Summary", input.summary),
|
|
26833
|
+
section("Customer impact", input.customerImpact),
|
|
26834
|
+
"## Reproduction steps",
|
|
26835
|
+
"",
|
|
26836
|
+
formatList(input.reproductionSteps),
|
|
26837
|
+
"",
|
|
26838
|
+
section("Expected behavior", input.expected),
|
|
26839
|
+
section("Actual behavior", input.actual),
|
|
26840
|
+
"## Files changed / suspected",
|
|
26841
|
+
"",
|
|
26842
|
+
formatList(input.filesChanged),
|
|
26843
|
+
"",
|
|
26844
|
+
section("Local workaround / hotfix", input.workaround),
|
|
26845
|
+
section("Local patch diff", input.localPatchDiff)
|
|
26846
|
+
].join("\n");
|
|
26847
|
+
}
|
|
26848
|
+
async function maybeSendUpstream(payload) {
|
|
26849
|
+
const config2 = await loadConfig();
|
|
26850
|
+
const endpoint = config2.support?.bugReportEndpoint || process.env.EXE_BUG_REPORT_ENDPOINT;
|
|
26851
|
+
const token = config2.support?.bugReportToken || process.env.EXE_BUG_REPORT_TOKEN;
|
|
26852
|
+
if (!endpoint) {
|
|
26853
|
+
return "not_configured";
|
|
26854
|
+
}
|
|
26855
|
+
try {
|
|
26856
|
+
const parsed = new URL(endpoint);
|
|
26857
|
+
if (parsed.protocol !== "https:" && !["localhost", "127.0.0.1", "::1"].includes(parsed.hostname)) {
|
|
26858
|
+
return "failed: insecure endpoint rejected";
|
|
26859
|
+
}
|
|
26860
|
+
const response = await fetch(parsed, {
|
|
26861
|
+
method: "POST",
|
|
26862
|
+
headers: {
|
|
26863
|
+
"content-type": "application/json",
|
|
26864
|
+
...token ? { authorization: `Bearer ${token}` } : {}
|
|
26865
|
+
},
|
|
26866
|
+
body: JSON.stringify(payload),
|
|
26867
|
+
signal: AbortSignal.timeout(1e4)
|
|
26868
|
+
});
|
|
26869
|
+
if (!response.ok) return `failed: HTTP ${response.status}`;
|
|
26870
|
+
return "sent";
|
|
26871
|
+
} catch (err) {
|
|
26872
|
+
return `failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
26873
|
+
}
|
|
26874
|
+
}
|
|
26875
|
+
function registerCreateBugReport(server) {
|
|
26876
|
+
server.registerTool(
|
|
26877
|
+
"create_bug_report",
|
|
26878
|
+
{
|
|
26879
|
+
title: "Create Bug Report",
|
|
26880
|
+
description: "Classify and file an exe-os issue as upstream_bug, customer_customization, emergency_hotfix, or unclear. Writes a local report, stores memory, and optionally sends to AskExe support when a support endpoint is configured.",
|
|
26881
|
+
inputSchema: {
|
|
26882
|
+
title: z82.string().min(3).describe("Short descriptive title"),
|
|
26883
|
+
classification: CLASSIFICATION.describe(
|
|
26884
|
+
"upstream_bug = platform defect; customer_customization = local preference; emergency_hotfix = temporary local patch; unclear = needs maintainer triage"
|
|
26885
|
+
),
|
|
26886
|
+
severity: SEVERITY.default("p2").describe("p0 critical \u2192 p3 low"),
|
|
26887
|
+
summary: z82.string().min(10).describe("What happened and why it matters"),
|
|
26888
|
+
customer_impact: z82.string().optional().describe("How this affects the customer/founder"),
|
|
26889
|
+
reproduction_steps: z82.array(z82.string()).optional().describe("Steps to reproduce"),
|
|
26890
|
+
expected: z82.string().optional().describe("Expected behavior"),
|
|
26891
|
+
actual: z82.string().optional().describe("Actual behavior"),
|
|
26892
|
+
files_changed: z82.array(z82.string()).optional().describe("Files changed or suspected"),
|
|
26893
|
+
workaround: z82.string().optional().describe("Temporary local workaround/hotfix, if any"),
|
|
26894
|
+
local_patch_diff: z82.string().optional().describe("Small local diff or patch summary"),
|
|
26895
|
+
package_version: z82.string().optional().describe("Installed @askexenow/exe-os version"),
|
|
26896
|
+
project_name: z82.string().optional().describe("Project/customer context"),
|
|
26897
|
+
send_upstream: z82.boolean().default(true).describe("Attempt to POST to configured AskExe support endpoint")
|
|
26898
|
+
}
|
|
26899
|
+
},
|
|
26900
|
+
async ({
|
|
26901
|
+
title,
|
|
26902
|
+
classification,
|
|
26903
|
+
severity,
|
|
26904
|
+
summary,
|
|
26905
|
+
customer_impact,
|
|
26906
|
+
reproduction_steps,
|
|
26907
|
+
expected,
|
|
26908
|
+
actual,
|
|
26909
|
+
files_changed,
|
|
26910
|
+
workaround,
|
|
26911
|
+
local_patch_diff,
|
|
26912
|
+
package_version,
|
|
26913
|
+
project_name,
|
|
26914
|
+
send_upstream
|
|
26915
|
+
}) => {
|
|
26916
|
+
const { agentId, agentRole } = getActiveAgent();
|
|
26917
|
+
const id = crypto19.randomUUID();
|
|
26918
|
+
const version = package_version ?? "unknown";
|
|
26919
|
+
const markdown = buildMarkdown({
|
|
26920
|
+
id,
|
|
26921
|
+
title,
|
|
26922
|
+
classification,
|
|
26923
|
+
severity,
|
|
26924
|
+
agentId,
|
|
26925
|
+
agentRole,
|
|
26926
|
+
packageVersion: version,
|
|
26927
|
+
summary,
|
|
26928
|
+
customerImpact: customer_impact,
|
|
26929
|
+
expected,
|
|
26930
|
+
actual,
|
|
26931
|
+
workaround,
|
|
26932
|
+
localPatchDiff: local_patch_diff,
|
|
26933
|
+
reproductionSteps: reproduction_steps,
|
|
26934
|
+
filesChanged: files_changed,
|
|
26935
|
+
projectName: project_name
|
|
26936
|
+
});
|
|
26937
|
+
const outDir = path49.join(EXE_AI_DIR, "bug-reports");
|
|
26938
|
+
await mkdir6(outDir, { recursive: true });
|
|
26939
|
+
const reportPath = path49.join(outDir, `${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}-${slugify2(title)}-${id.slice(0, 8)}.md`);
|
|
26940
|
+
await writeFile7(reportPath, markdown, "utf-8");
|
|
26941
|
+
let vector = null;
|
|
26942
|
+
try {
|
|
26943
|
+
vector = await embed(markdown);
|
|
26944
|
+
} catch {
|
|
26945
|
+
vector = null;
|
|
26946
|
+
}
|
|
26947
|
+
await writeMemory({
|
|
26948
|
+
id,
|
|
26949
|
+
agent_id: agentId,
|
|
26950
|
+
agent_role: agentRole,
|
|
26951
|
+
session_id: process.env.SESSION_ID ?? "manual",
|
|
26952
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26953
|
+
tool_name: "create_bug_report",
|
|
26954
|
+
project_name: project_name ?? "support",
|
|
26955
|
+
has_error: classification === "upstream_bug" || classification === "emergency_hotfix",
|
|
26956
|
+
raw_text: markdown,
|
|
26957
|
+
vector,
|
|
26958
|
+
source_path: reportPath,
|
|
26959
|
+
source_type: "bug_report",
|
|
26960
|
+
memory_type: "bug_report",
|
|
26961
|
+
tier: 1,
|
|
26962
|
+
importance: severity === "p0" ? 10 : severity === "p1" ? 9 : 7,
|
|
26963
|
+
intent: "report",
|
|
26964
|
+
domain: "support",
|
|
26965
|
+
file_paths: files_changed ? JSON.stringify(files_changed) : null
|
|
26966
|
+
});
|
|
26967
|
+
await flushBatch();
|
|
26968
|
+
const upstreamStatus = send_upstream ? await maybeSendUpstream({
|
|
26969
|
+
id,
|
|
26970
|
+
title,
|
|
26971
|
+
classification,
|
|
26972
|
+
severity,
|
|
26973
|
+
summary,
|
|
26974
|
+
customer_impact,
|
|
26975
|
+
reproduction_steps,
|
|
26976
|
+
expected,
|
|
26977
|
+
actual,
|
|
26978
|
+
files_changed,
|
|
26979
|
+
workaround,
|
|
26980
|
+
local_patch_diff,
|
|
26981
|
+
package_version: version,
|
|
26982
|
+
project_name,
|
|
26983
|
+
agent_id: agentId,
|
|
26984
|
+
agent_role: agentRole,
|
|
26985
|
+
report_path: reportPath,
|
|
26986
|
+
markdown
|
|
26987
|
+
}) : "skipped";
|
|
26988
|
+
return {
|
|
26989
|
+
content: [
|
|
26990
|
+
{
|
|
26991
|
+
type: "text",
|
|
26992
|
+
text: `Bug report created.
|
|
26993
|
+
ID: ${id}
|
|
26994
|
+
Classification: ${classification}
|
|
26995
|
+
Local report: ${reportPath}
|
|
26996
|
+
Memory stored: ${id}
|
|
26997
|
+
Upstream status: ${upstreamStatus}`
|
|
26998
|
+
}
|
|
26999
|
+
]
|
|
27000
|
+
};
|
|
27001
|
+
}
|
|
27002
|
+
);
|
|
27003
|
+
}
|
|
27004
|
+
var CLASSIFICATION, SEVERITY;
|
|
27005
|
+
var init_create_bug_report = __esm({
|
|
27006
|
+
"src/mcp/tools/create-bug-report.ts"() {
|
|
27007
|
+
"use strict";
|
|
27008
|
+
init_embedder();
|
|
27009
|
+
init_active_agent();
|
|
27010
|
+
init_config();
|
|
27011
|
+
init_store();
|
|
27012
|
+
CLASSIFICATION = z82.enum([
|
|
27013
|
+
"upstream_bug",
|
|
27014
|
+
"customer_customization",
|
|
27015
|
+
"emergency_hotfix",
|
|
27016
|
+
"unclear"
|
|
27017
|
+
]);
|
|
27018
|
+
SEVERITY = z82.enum(["p0", "p1", "p2", "p3"]);
|
|
27019
|
+
}
|
|
27020
|
+
});
|
|
27021
|
+
|
|
26797
27022
|
// src/mcp/tool-gates.ts
|
|
26798
27023
|
function isToolAllowed(registerFnName) {
|
|
26799
27024
|
const role = process.env.AGENT_ROLE;
|
|
@@ -26855,6 +27080,7 @@ var init_tool_gates = __esm({
|
|
|
26855
27080
|
registerBehavior: "core",
|
|
26856
27081
|
registerStoreDecision: "core",
|
|
26857
27082
|
registerGetDecision: "core",
|
|
27083
|
+
registerCreateBugReport: "core",
|
|
26858
27084
|
registerIdentity: "core",
|
|
26859
27085
|
registerGetIdentity: "core",
|
|
26860
27086
|
registerUpdateIdentity: "core",
|
|
@@ -26887,6 +27113,7 @@ var init_tool_gates = __esm({
|
|
|
26887
27113
|
registerExportGraph: "graph-write",
|
|
26888
27114
|
// wiki
|
|
26889
27115
|
registerWiki: "wiki",
|
|
27116
|
+
registerCreateWikiPage: "wiki",
|
|
26890
27117
|
registerListWikiPages: "wiki",
|
|
26891
27118
|
registerGetWikiPage: "wiki",
|
|
26892
27119
|
// crm
|
|
@@ -27060,6 +27287,7 @@ function registerAllTools(server) {
|
|
|
27060
27287
|
}
|
|
27061
27288
|
gate("registerStoreDecision", registerStoreDecision);
|
|
27062
27289
|
gate("registerGetDecision", registerGetDecision);
|
|
27290
|
+
gate("registerCreateBugReport", registerCreateBugReport);
|
|
27063
27291
|
gate("registerGetAgentSpend", registerGetAgentSpend);
|
|
27064
27292
|
gate("registerGetGraphStats", registerGetGraphStats);
|
|
27065
27293
|
gate("registerGetEntityNeighbors", registerGetEntityNeighbors);
|
|
@@ -27181,6 +27409,7 @@ var init_register_tools = __esm({
|
|
|
27181
27409
|
init_list_licenses();
|
|
27182
27410
|
init_activate_license();
|
|
27183
27411
|
init_query_company_brain();
|
|
27412
|
+
init_create_bug_report();
|
|
27184
27413
|
init_tool_gates();
|
|
27185
27414
|
}
|
|
27186
27415
|
});
|
|
@@ -27406,7 +27635,7 @@ __export(task_enforcement_exports, {
|
|
|
27406
27635
|
sendNudge: () => sendNudge
|
|
27407
27636
|
});
|
|
27408
27637
|
import { writeFileSync as writeFileSync22 } from "fs";
|
|
27409
|
-
import
|
|
27638
|
+
import path50 from "path";
|
|
27410
27639
|
function writeAuditEntry(entry) {
|
|
27411
27640
|
try {
|
|
27412
27641
|
const line = JSON.stringify(entry) + "\n";
|
|
@@ -27581,7 +27810,7 @@ var init_task_enforcement = __esm({
|
|
|
27581
27810
|
"What do you need?"
|
|
27582
27811
|
];
|
|
27583
27812
|
MANAGER_ROLES = ["COO", "CTO"];
|
|
27584
|
-
AUDIT_LOG_PATH =
|
|
27813
|
+
AUDIT_LOG_PATH = path50.join(
|
|
27585
27814
|
process.env.HOME ?? process.env.USERPROFILE ?? "/tmp",
|
|
27586
27815
|
".exe-os",
|
|
27587
27816
|
"enforcement-audit.jsonl"
|
|
@@ -27599,9 +27828,9 @@ __export(update_check_exports, {
|
|
|
27599
27828
|
});
|
|
27600
27829
|
import { execSync as execSync15 } from "child_process";
|
|
27601
27830
|
import { readFileSync as readFileSync31 } from "fs";
|
|
27602
|
-
import
|
|
27831
|
+
import path51 from "path";
|
|
27603
27832
|
function getLocalVersion(packageRoot) {
|
|
27604
|
-
const pkgPath =
|
|
27833
|
+
const pkgPath = path51.join(packageRoot, "package.json");
|
|
27605
27834
|
const pkg = JSON.parse(readFileSync31(pkgPath, "utf-8"));
|
|
27606
27835
|
return pkg.version;
|
|
27607
27836
|
}
|
|
@@ -27645,16 +27874,16 @@ __export(ws_auth_exports, {
|
|
|
27645
27874
|
deriveWsAuthToken: () => deriveWsAuthToken,
|
|
27646
27875
|
hashAuthToken: () => hashAuthToken
|
|
27647
27876
|
});
|
|
27648
|
-
import
|
|
27877
|
+
import crypto20 from "crypto";
|
|
27649
27878
|
function deriveWsAuthToken(masterKey) {
|
|
27650
|
-
return Buffer.from(
|
|
27879
|
+
return Buffer.from(crypto20.hkdfSync("sha256", masterKey, "", WS_AUTH_HKDF_INFO, 32));
|
|
27651
27880
|
}
|
|
27652
27881
|
function deriveOrgId(masterKey) {
|
|
27653
|
-
const raw = Buffer.from(
|
|
27654
|
-
return
|
|
27882
|
+
const raw = Buffer.from(crypto20.hkdfSync("sha256", masterKey, "", ORG_ID_HKDF_INFO, 32));
|
|
27883
|
+
return crypto20.createHash("sha256").update(raw).digest("hex").slice(0, 32);
|
|
27655
27884
|
}
|
|
27656
27885
|
function hashAuthToken(token) {
|
|
27657
|
-
return
|
|
27886
|
+
return crypto20.createHash("sha256").update(token).digest("hex");
|
|
27658
27887
|
}
|
|
27659
27888
|
var WS_AUTH_HKDF_INFO, ORG_ID_HKDF_INFO;
|
|
27660
27889
|
var init_ws_auth = __esm({
|
|
@@ -27672,10 +27901,10 @@ __export(device_registry_exports, {
|
|
|
27672
27901
|
resolveTargetDevice: () => resolveTargetDevice,
|
|
27673
27902
|
setFriendlyName: () => setFriendlyName
|
|
27674
27903
|
});
|
|
27675
|
-
import
|
|
27904
|
+
import crypto21 from "crypto";
|
|
27676
27905
|
import os21 from "os";
|
|
27677
27906
|
import { readFileSync as readFileSync32, writeFileSync as writeFileSync23, mkdirSync as mkdirSync18, existsSync as existsSync38 } from "fs";
|
|
27678
|
-
import
|
|
27907
|
+
import path52 from "path";
|
|
27679
27908
|
function getDeviceInfo() {
|
|
27680
27909
|
if (existsSync38(DEVICE_JSON_PATH)) {
|
|
27681
27910
|
try {
|
|
@@ -27689,11 +27918,11 @@ function getDeviceInfo() {
|
|
|
27689
27918
|
}
|
|
27690
27919
|
const hostname = os21.hostname();
|
|
27691
27920
|
const info = {
|
|
27692
|
-
deviceId:
|
|
27921
|
+
deviceId: crypto21.randomUUID(),
|
|
27693
27922
|
friendlyName: hostname.replace(/\./g, "-").toLowerCase(),
|
|
27694
27923
|
hostname
|
|
27695
27924
|
};
|
|
27696
|
-
mkdirSync18(
|
|
27925
|
+
mkdirSync18(path52.dirname(DEVICE_JSON_PATH), { recursive: true });
|
|
27697
27926
|
writeFileSync23(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
|
|
27698
27927
|
return info;
|
|
27699
27928
|
}
|
|
@@ -27734,7 +27963,7 @@ var init_device_registry = __esm({
|
|
|
27734
27963
|
"src/lib/device-registry.ts"() {
|
|
27735
27964
|
"use strict";
|
|
27736
27965
|
init_config();
|
|
27737
|
-
DEVICE_JSON_PATH =
|
|
27966
|
+
DEVICE_JSON_PATH = path52.join(EXE_AI_DIR, "device.json");
|
|
27738
27967
|
}
|
|
27739
27968
|
});
|
|
27740
27969
|
|
|
@@ -27951,7 +28180,7 @@ import net2 from "net";
|
|
|
27951
28180
|
import { createServer as createHttpServer } from "http";
|
|
27952
28181
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
27953
28182
|
import { writeFileSync as writeFileSync24, unlinkSync as unlinkSync13, mkdirSync as mkdirSync19, existsSync as existsSync39, readFileSync as readFileSync33, chmodSync as chmodSync2 } from "fs";
|
|
27954
|
-
import
|
|
28183
|
+
import path53 from "path";
|
|
27955
28184
|
|
|
27956
28185
|
// src/lib/orchestration-metrics.ts
|
|
27957
28186
|
init_config();
|
|
@@ -28023,8 +28252,8 @@ function initMetrics() {
|
|
|
28023
28252
|
|
|
28024
28253
|
// src/lib/exe-daemon.ts
|
|
28025
28254
|
init_memory_write_governor();
|
|
28026
|
-
var SOCKET_PATH2 = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ??
|
|
28027
|
-
var PID_PATH3 = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ??
|
|
28255
|
+
var SOCKET_PATH2 = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path53.join(EXE_AI_DIR, "exed.sock");
|
|
28256
|
+
var PID_PATH3 = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path53.join(EXE_AI_DIR, "exed.pid");
|
|
28028
28257
|
var MODEL_FILE = "jina-embeddings-v5-small-q4_k_m.gguf";
|
|
28029
28258
|
var IDLE_TIMEOUT_MS2 = 15 * 60 * 1e3;
|
|
28030
28259
|
var REVIEW_POLL_INTERVAL_MS = 60 * 1e3;
|
|
@@ -28052,7 +28281,7 @@ function enqueue(queue, entry) {
|
|
|
28052
28281
|
queue.push(entry);
|
|
28053
28282
|
}
|
|
28054
28283
|
async function loadModel() {
|
|
28055
|
-
const modelPath =
|
|
28284
|
+
const modelPath = path53.join(MODELS_DIR, MODEL_FILE);
|
|
28056
28285
|
if (!existsSync39(modelPath)) {
|
|
28057
28286
|
process.stderr.write(`[exed] No model at ${modelPath} \u2014 running without embeddings (VPS mode).
|
|
28058
28287
|
`);
|
|
@@ -28451,14 +28680,14 @@ function startMemoryQueueDrain() {
|
|
|
28451
28680
|
`);
|
|
28452
28681
|
}
|
|
28453
28682
|
function startServer() {
|
|
28454
|
-
mkdirSync19(
|
|
28683
|
+
mkdirSync19(path53.dirname(SOCKET_PATH2), { recursive: true });
|
|
28455
28684
|
try {
|
|
28456
|
-
chmodSync2(
|
|
28685
|
+
chmodSync2(path53.dirname(SOCKET_PATH2), 448);
|
|
28457
28686
|
} catch {
|
|
28458
28687
|
}
|
|
28459
28688
|
_daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV2] ?? null);
|
|
28460
28689
|
for (const oldFile of ["embed.sock", "embed.pid"]) {
|
|
28461
|
-
const oldPath =
|
|
28690
|
+
const oldPath = path53.join(path53.dirname(SOCKET_PATH2), oldFile);
|
|
28462
28691
|
try {
|
|
28463
28692
|
if (oldFile.endsWith(".pid")) {
|
|
28464
28693
|
const pid = parseInt(readFileSync33(oldPath, "utf8").trim(), 10);
|
|
@@ -28934,7 +29163,7 @@ function startGraphExtraction() {
|
|
|
28934
29163
|
`);
|
|
28935
29164
|
}
|
|
28936
29165
|
var AGENT_STATS_INTERVAL_MS = 60 * 1e3;
|
|
28937
|
-
var AGENT_STATS_PATH =
|
|
29166
|
+
var AGENT_STATS_PATH = path53.join(EXE_AI_DIR, "agent-stats.json");
|
|
28938
29167
|
async function writeAgentStats() {
|
|
28939
29168
|
fired("agent_stats");
|
|
28940
29169
|
if (!await ensureStoreForPolling()) return;
|
|
@@ -29111,11 +29340,11 @@ function startIntercomQueueDrain() {
|
|
|
29111
29340
|
const hasInProgressTask = (session) => {
|
|
29112
29341
|
try {
|
|
29113
29342
|
const { baseAgentName: ban } = (init_employees(), __toCommonJS(employees_exports));
|
|
29114
|
-
const
|
|
29343
|
+
const path54 = __require("path");
|
|
29115
29344
|
const { existsSync: existsSync40 } = __require("fs");
|
|
29116
29345
|
const os23 = __require("os");
|
|
29117
29346
|
const agent = ban(session.split("-")[0] ?? session);
|
|
29118
|
-
const markerPath =
|
|
29347
|
+
const markerPath = path54.join(os23.homedir(), ".exe-os", "session-cache", `current-task-${agent}.json`);
|
|
29119
29348
|
return existsSync40(markerPath);
|
|
29120
29349
|
} catch {
|
|
29121
29350
|
return false;
|
|
@@ -3644,6 +3644,12 @@ var init_platform_procedures = __esm({
|
|
|
3644
3644
|
priority: "p0",
|
|
3645
3645
|
content: "NEVER: (1) Access the database directly \u2014 it's SQLCipher encrypted, always fails. Use MCP tools only. (2) Manually spawn tmux sessions \u2014 create_task handles it. (3) Run git checkout main \u2014 agents work in worktrees. (4) Modify another agent's in-progress task. (5) Push to remote \u2014 the COO reviews and pushes. (6) Skip update_task(done) \u2014 it's the ONLY way your work gets reviewed. (7) Run git init."
|
|
3646
3646
|
},
|
|
3647
|
+
{
|
|
3648
|
+
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
3649
|
+
domain: "support",
|
|
3650
|
+
priority: "p0",
|
|
3651
|
+
content: "Before editing platform code for a customer issue, classify it. Upstream bug = reproducible exe-os/platform defect; call create_bug_report with repro/version/workaround and avoid permanent local patches unless founder approves. Customer customization = identity, behavior, procedure, config, branding, workflow; store it in customer-owned layers, not platform code. Emergency hotfix = temporary only; document files/diff and re-check after npm update."
|
|
3652
|
+
},
|
|
3647
3653
|
// --- Operations ---
|
|
3648
3654
|
{
|
|
3649
3655
|
title: "Managers must supervise deployed workers",
|
|
@@ -3712,7 +3718,7 @@ var init_platform_procedures = __esm({
|
|
|
3712
3718
|
title: "MCP tools \u2014 identity, behavior, and decisions",
|
|
3713
3719
|
domain: "tool-use",
|
|
3714
3720
|
priority: "p1",
|
|
3715
|
-
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query."
|
|
3721
|
+
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query. create_bug_report: classify/file upstream bugs, customer customizations, and emergency hotfixes."
|
|
3716
3722
|
},
|
|
3717
3723
|
{
|
|
3718
3724
|
title: "MCP tools \u2014 communication and messaging",
|
package/dist/lib/schedules.js
CHANGED
|
@@ -3006,6 +3006,12 @@ var init_platform_procedures = __esm({
|
|
|
3006
3006
|
priority: "p0",
|
|
3007
3007
|
content: "NEVER: (1) Access the database directly \u2014 it's SQLCipher encrypted, always fails. Use MCP tools only. (2) Manually spawn tmux sessions \u2014 create_task handles it. (3) Run git checkout main \u2014 agents work in worktrees. (4) Modify another agent's in-progress task. (5) Push to remote \u2014 the COO reviews and pushes. (6) Skip update_task(done) \u2014 it's the ONLY way your work gets reviewed. (7) Run git init."
|
|
3008
3008
|
},
|
|
3009
|
+
{
|
|
3010
|
+
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
3011
|
+
domain: "support",
|
|
3012
|
+
priority: "p0",
|
|
3013
|
+
content: "Before editing platform code for a customer issue, classify it. Upstream bug = reproducible exe-os/platform defect; call create_bug_report with repro/version/workaround and avoid permanent local patches unless founder approves. Customer customization = identity, behavior, procedure, config, branding, workflow; store it in customer-owned layers, not platform code. Emergency hotfix = temporary only; document files/diff and re-check after npm update."
|
|
3014
|
+
},
|
|
3009
3015
|
// --- Operations ---
|
|
3010
3016
|
{
|
|
3011
3017
|
title: "Managers must supervise deployed workers",
|
|
@@ -3074,7 +3080,7 @@ var init_platform_procedures = __esm({
|
|
|
3074
3080
|
title: "MCP tools \u2014 identity, behavior, and decisions",
|
|
3075
3081
|
domain: "tool-use",
|
|
3076
3082
|
priority: "p1",
|
|
3077
|
-
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query."
|
|
3083
|
+
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query. create_bug_report: classify/file upstream bugs, customer customizations, and emergency hotfixes."
|
|
3078
3084
|
},
|
|
3079
3085
|
{
|
|
3080
3086
|
title: "MCP tools \u2014 communication and messaging",
|
package/dist/lib/store.js
CHANGED
|
@@ -3006,6 +3006,12 @@ var init_platform_procedures = __esm({
|
|
|
3006
3006
|
priority: "p0",
|
|
3007
3007
|
content: "NEVER: (1) Access the database directly \u2014 it's SQLCipher encrypted, always fails. Use MCP tools only. (2) Manually spawn tmux sessions \u2014 create_task handles it. (3) Run git checkout main \u2014 agents work in worktrees. (4) Modify another agent's in-progress task. (5) Push to remote \u2014 the COO reviews and pushes. (6) Skip update_task(done) \u2014 it's the ONLY way your work gets reviewed. (7) Run git init."
|
|
3008
3008
|
},
|
|
3009
|
+
{
|
|
3010
|
+
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
3011
|
+
domain: "support",
|
|
3012
|
+
priority: "p0",
|
|
3013
|
+
content: "Before editing platform code for a customer issue, classify it. Upstream bug = reproducible exe-os/platform defect; call create_bug_report with repro/version/workaround and avoid permanent local patches unless founder approves. Customer customization = identity, behavior, procedure, config, branding, workflow; store it in customer-owned layers, not platform code. Emergency hotfix = temporary only; document files/diff and re-check after npm update."
|
|
3014
|
+
},
|
|
3009
3015
|
// --- Operations ---
|
|
3010
3016
|
{
|
|
3011
3017
|
title: "Managers must supervise deployed workers",
|
|
@@ -3074,7 +3080,7 @@ var init_platform_procedures = __esm({
|
|
|
3074
3080
|
title: "MCP tools \u2014 identity, behavior, and decisions",
|
|
3075
3081
|
domain: "tool-use",
|
|
3076
3082
|
priority: "p1",
|
|
3077
|
-
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query."
|
|
3083
|
+
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query. create_bug_report: classify/file upstream bugs, customer customizations, and emergency hotfixes."
|
|
3078
3084
|
},
|
|
3079
3085
|
{
|
|
3080
3086
|
title: "MCP tools \u2014 communication and messaging",
|