@askexenow/exe-os 0.9.10 → 0.9.11
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/cli.js +150 -8
- package/dist/bin/exe-boot.js +150 -8
- package/dist/bin/exe-dispatch.js +155 -8
- package/dist/bin/exe-gateway.js +531 -166
- package/dist/bin/exe-link.js +6 -0
- package/dist/bin/exe-session-cleanup.js +28 -8
- package/dist/bin/git-sweep.js +157 -10
- package/dist/bin/scan-tasks.js +155 -8
- package/dist/bin/setup.js +6 -0
- package/dist/gateway/index.js +144 -8
- package/dist/hooks/bug-report-worker.js +394 -258
- package/dist/hooks/codex-stop-task-finalizer.js +10 -8
- package/dist/hooks/commit-complete.js +155 -8
- package/dist/hooks/ingest-worker.js +155 -8
- package/dist/hooks/pre-compact.js +155 -8
- package/dist/hooks/prompt-submit.js +28 -8
- package/dist/hooks/session-end.js +157 -10
- package/dist/hooks/summary-worker.js +6 -0
- package/dist/index.js +144 -8
- package/dist/lib/cloud-sync.js +6 -0
- package/dist/lib/exe-daemon.js +28 -8
- package/dist/lib/messaging.js +10 -8
- package/dist/lib/tasks.js +460 -313
- package/dist/lib/tmux-routing.js +155 -8
- package/dist/mcp/server.js +396 -254
- package/dist/mcp/tools/create-task.js +449 -313
- package/dist/mcp/tools/send-message.js +10 -8
- package/dist/mcp/tools/update-task.js +460 -313
- package/dist/runtime/index.js +155 -8
- package/dist/tui/App.js +144 -8
- package/package.json +1 -1
package/dist/runtime/index.js
CHANGED
|
@@ -270,6 +270,17 @@ function isCoordinatorName(agentName, employees = loadEmployeesSync()) {
|
|
|
270
270
|
if (!agentName) return false;
|
|
271
271
|
return agentName.toLowerCase() === getCoordinatorName(employees).toLowerCase();
|
|
272
272
|
}
|
|
273
|
+
async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
274
|
+
if (!existsSync3(employeesPath)) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
const raw = await readFile2(employeesPath, "utf-8");
|
|
278
|
+
try {
|
|
279
|
+
return JSON.parse(raw);
|
|
280
|
+
} catch {
|
|
281
|
+
return [];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
273
284
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
274
285
|
if (!existsSync3(employeesPath)) return [];
|
|
275
286
|
try {
|
|
@@ -4037,8 +4048,35 @@ var init_tasks_crud = __esm({
|
|
|
4037
4048
|
});
|
|
4038
4049
|
|
|
4039
4050
|
// src/lib/tasks-review.ts
|
|
4051
|
+
var tasks_review_exports = {};
|
|
4052
|
+
__export(tasks_review_exports, {
|
|
4053
|
+
cleanupOrphanedReviews: () => cleanupOrphanedReviews,
|
|
4054
|
+
cleanupReviewFile: () => cleanupReviewFile,
|
|
4055
|
+
countNewPendingReviewsSince: () => countNewPendingReviewsSince,
|
|
4056
|
+
countPendingReviews: () => countPendingReviews,
|
|
4057
|
+
createReviewForCompletedTask: () => createReviewForCompletedTask,
|
|
4058
|
+
formatAge: () => formatAge,
|
|
4059
|
+
getReviewChecklist: () => getReviewChecklist,
|
|
4060
|
+
isStale: () => isStale,
|
|
4061
|
+
listPendingReviews: () => listPendingReviews
|
|
4062
|
+
});
|
|
4040
4063
|
import path15 from "path";
|
|
4041
4064
|
import { existsSync as existsSync13, readdirSync as readdirSync2, unlinkSync as unlinkSync4 } from "fs";
|
|
4065
|
+
function formatAge(isoTimestamp) {
|
|
4066
|
+
if (!isoTimestamp) return "";
|
|
4067
|
+
const ms = Date.now() - new Date(isoTimestamp).getTime();
|
|
4068
|
+
if (ms < 0) return "just now";
|
|
4069
|
+
const minutes = Math.floor(ms / 6e4);
|
|
4070
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
4071
|
+
const hours = Math.floor(minutes / 60);
|
|
4072
|
+
if (hours < 24) return `${hours}h ago`;
|
|
4073
|
+
const days = Math.floor(hours / 24);
|
|
4074
|
+
return `${days}d ago`;
|
|
4075
|
+
}
|
|
4076
|
+
function isStale(isoTimestamp) {
|
|
4077
|
+
if (!isoTimestamp) return false;
|
|
4078
|
+
return Date.now() - new Date(isoTimestamp).getTime() > 24 * 60 * 60 * 1e3;
|
|
4079
|
+
}
|
|
4042
4080
|
async function countPendingReviews(sessionScope) {
|
|
4043
4081
|
const client = getClient();
|
|
4044
4082
|
const scope = strictSessionScopeFilter(
|
|
@@ -4159,6 +4197,95 @@ function getReviewChecklist(role, agent, taskSlug) {
|
|
|
4159
4197
|
]
|
|
4160
4198
|
};
|
|
4161
4199
|
}
|
|
4200
|
+
async function createReviewForCompletedTask(row, result, _baseDir, now) {
|
|
4201
|
+
const taskFile = String(row.task_file);
|
|
4202
|
+
const employees = await loadEmployees();
|
|
4203
|
+
const coordinatorName = getCoordinatorName(employees);
|
|
4204
|
+
if (isCoordinatorName(String(row.assigned_to), employees)) return;
|
|
4205
|
+
if (String(row.title).startsWith("Review:")) return;
|
|
4206
|
+
const fileName = taskFile.split("/").pop() ?? "";
|
|
4207
|
+
if (fileName.startsWith("review-") && String(row.assigned_by) === "system") return;
|
|
4208
|
+
if (fileName.startsWith("review-") && String(row.assigned_to) === "system") return;
|
|
4209
|
+
const client = getClient();
|
|
4210
|
+
const agent = String(row.assigned_to);
|
|
4211
|
+
const rawReviewer = row.reviewer || row.assigned_by;
|
|
4212
|
+
const reviewer = rawReviewer ? String(rawReviewer) : coordinatorName;
|
|
4213
|
+
const currentStatus = String(row.status ?? "");
|
|
4214
|
+
if (currentStatus === "done") return;
|
|
4215
|
+
const existingResult = String(row.result ?? "");
|
|
4216
|
+
if (existingResult.includes("## Review notes")) return;
|
|
4217
|
+
let reviewerRole = "unknown";
|
|
4218
|
+
try {
|
|
4219
|
+
const emp = getEmployee(employees, reviewer);
|
|
4220
|
+
if (emp) reviewerRole = emp.role;
|
|
4221
|
+
} catch {
|
|
4222
|
+
}
|
|
4223
|
+
const taskTitle = String(row.title);
|
|
4224
|
+
const taskSlug = taskFile.split("/").pop()?.replace(".md", "") ?? "unknown";
|
|
4225
|
+
const { lens, checklist } = getReviewChecklist(reviewerRole, agent, taskSlug);
|
|
4226
|
+
process.stderr.write(
|
|
4227
|
+
`[review] Annotating "${taskTitle}" for review by ${reviewer} (${reviewerRole})
|
|
4228
|
+
`
|
|
4229
|
+
);
|
|
4230
|
+
const reviewNotes = [
|
|
4231
|
+
`
|
|
4232
|
+
---
|
|
4233
|
+
## Review notes`,
|
|
4234
|
+
`Review lens: ${lens}`,
|
|
4235
|
+
`Reviewer: **${reviewer}** (${reviewerRole})`,
|
|
4236
|
+
"",
|
|
4237
|
+
"### Checklist",
|
|
4238
|
+
...checklist,
|
|
4239
|
+
"",
|
|
4240
|
+
"### Verdict",
|
|
4241
|
+
"- **Approved:** mark this task as done",
|
|
4242
|
+
"- **Needs work:** re-open with notes"
|
|
4243
|
+
].join("\n");
|
|
4244
|
+
const originalTaskId = String(row.id);
|
|
4245
|
+
const updatedResult = (result ?? "No result summary provided") + reviewNotes;
|
|
4246
|
+
await client.execute({
|
|
4247
|
+
sql: `UPDATE tasks SET result = ?, status = 'needs_review', updated_at = ?
|
|
4248
|
+
WHERE id = ?`,
|
|
4249
|
+
args: [updatedResult, now, originalTaskId]
|
|
4250
|
+
});
|
|
4251
|
+
orgBus.emit({
|
|
4252
|
+
type: "review_created",
|
|
4253
|
+
reviewId: originalTaskId,
|
|
4254
|
+
employee: agent,
|
|
4255
|
+
reviewer,
|
|
4256
|
+
timestamp: now
|
|
4257
|
+
});
|
|
4258
|
+
await writeNotification({
|
|
4259
|
+
agentId: agent,
|
|
4260
|
+
agentRole: String(row.assigned_to),
|
|
4261
|
+
event: "task_complete",
|
|
4262
|
+
project: String(row.project_name),
|
|
4263
|
+
summary: `completed "${taskTitle}" \u2014 ready for review`,
|
|
4264
|
+
taskFile
|
|
4265
|
+
});
|
|
4266
|
+
const originalPriority = String(row.priority).toLowerCase();
|
|
4267
|
+
const autoApprove = originalPriority === "p2" && result?.toLowerCase().includes("tests pass");
|
|
4268
|
+
if (!autoApprove) {
|
|
4269
|
+
try {
|
|
4270
|
+
const key = getSessionKey();
|
|
4271
|
+
const exeSession = getParentExe(key);
|
|
4272
|
+
if (exeSession) {
|
|
4273
|
+
sendIntercom(exeSession);
|
|
4274
|
+
}
|
|
4275
|
+
} catch {
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
if (autoApprove) {
|
|
4279
|
+
process.stderr.write(
|
|
4280
|
+
`[review] Auto-approving "${taskTitle}" (P2 + tests pass)
|
|
4281
|
+
`
|
|
4282
|
+
);
|
|
4283
|
+
await client.execute({
|
|
4284
|
+
sql: "UPDATE tasks SET status = 'done', updated_at = ? WHERE id = ?",
|
|
4285
|
+
args: [now, originalTaskId]
|
|
4286
|
+
});
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4162
4289
|
async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
4163
4290
|
if (String(row.assigned_by) !== "system" || !taskFile.includes("review-")) return;
|
|
4164
4291
|
try {
|
|
@@ -5584,15 +5711,17 @@ function sendIntercom(targetSession) {
|
|
|
5584
5711
|
logIntercom(`QUEUED \u2192 ${targetSession} (session busy)${batched2 > 0 ? ` [${batched2} batched]` : ""}`);
|
|
5585
5712
|
return "queued";
|
|
5586
5713
|
}
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5714
|
+
if (sessionState !== "idle") {
|
|
5715
|
+
try {
|
|
5716
|
+
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
5717
|
+
const agent = baseAgentName(rawAgent);
|
|
5718
|
+
const markerPath = path18.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
5719
|
+
if (existsSync14(markerPath)) {
|
|
5720
|
+
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
|
|
5721
|
+
return "debounced";
|
|
5722
|
+
}
|
|
5723
|
+
} catch {
|
|
5594
5724
|
}
|
|
5595
|
-
} catch {
|
|
5596
5725
|
}
|
|
5597
5726
|
try {
|
|
5598
5727
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
@@ -5663,6 +5792,24 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
5663
5792
|
try {
|
|
5664
5793
|
const sessions = transport.listSessions();
|
|
5665
5794
|
if (!sessions.includes(coordinatorSession)) return false;
|
|
5795
|
+
try {
|
|
5796
|
+
const { countPendingReviews: countPendingReviews2 } = (init_tasks_review(), __toCommonJS(tasks_review_exports));
|
|
5797
|
+
const pending = countPendingReviews2(coordinatorSession);
|
|
5798
|
+
if (pending instanceof Promise) {
|
|
5799
|
+
pending.then((count) => {
|
|
5800
|
+
if (count > 0) {
|
|
5801
|
+
execSync7(
|
|
5802
|
+
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
5803
|
+
{ timeout: 3e3 }
|
|
5804
|
+
);
|
|
5805
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
5806
|
+
}
|
|
5807
|
+
}).catch(() => {
|
|
5808
|
+
});
|
|
5809
|
+
return true;
|
|
5810
|
+
}
|
|
5811
|
+
} catch {
|
|
5812
|
+
}
|
|
5666
5813
|
execSync7(
|
|
5667
5814
|
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
5668
5815
|
{ timeout: 3e3 }
|
package/dist/tui/App.js
CHANGED
|
@@ -4769,8 +4769,35 @@ var init_tasks_crud = __esm({
|
|
|
4769
4769
|
});
|
|
4770
4770
|
|
|
4771
4771
|
// src/lib/tasks-review.ts
|
|
4772
|
+
var tasks_review_exports = {};
|
|
4773
|
+
__export(tasks_review_exports, {
|
|
4774
|
+
cleanupOrphanedReviews: () => cleanupOrphanedReviews,
|
|
4775
|
+
cleanupReviewFile: () => cleanupReviewFile,
|
|
4776
|
+
countNewPendingReviewsSince: () => countNewPendingReviewsSince,
|
|
4777
|
+
countPendingReviews: () => countPendingReviews,
|
|
4778
|
+
createReviewForCompletedTask: () => createReviewForCompletedTask,
|
|
4779
|
+
formatAge: () => formatAge,
|
|
4780
|
+
getReviewChecklist: () => getReviewChecklist,
|
|
4781
|
+
isStale: () => isStale,
|
|
4782
|
+
listPendingReviews: () => listPendingReviews
|
|
4783
|
+
});
|
|
4772
4784
|
import path14 from "path";
|
|
4773
4785
|
import { existsSync as existsSync14, readdirSync as readdirSync2, unlinkSync as unlinkSync4 } from "fs";
|
|
4786
|
+
function formatAge(isoTimestamp) {
|
|
4787
|
+
if (!isoTimestamp) return "";
|
|
4788
|
+
const ms = Date.now() - new Date(isoTimestamp).getTime();
|
|
4789
|
+
if (ms < 0) return "just now";
|
|
4790
|
+
const minutes = Math.floor(ms / 6e4);
|
|
4791
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
4792
|
+
const hours = Math.floor(minutes / 60);
|
|
4793
|
+
if (hours < 24) return `${hours}h ago`;
|
|
4794
|
+
const days = Math.floor(hours / 24);
|
|
4795
|
+
return `${days}d ago`;
|
|
4796
|
+
}
|
|
4797
|
+
function isStale(isoTimestamp) {
|
|
4798
|
+
if (!isoTimestamp) return false;
|
|
4799
|
+
return Date.now() - new Date(isoTimestamp).getTime() > 24 * 60 * 60 * 1e3;
|
|
4800
|
+
}
|
|
4774
4801
|
async function countPendingReviews(sessionScope) {
|
|
4775
4802
|
const client = getClient();
|
|
4776
4803
|
const scope = strictSessionScopeFilter(
|
|
@@ -4891,6 +4918,95 @@ function getReviewChecklist(role, agent, taskSlug) {
|
|
|
4891
4918
|
]
|
|
4892
4919
|
};
|
|
4893
4920
|
}
|
|
4921
|
+
async function createReviewForCompletedTask(row, result, _baseDir, now) {
|
|
4922
|
+
const taskFile = String(row.task_file);
|
|
4923
|
+
const employees = await loadEmployees();
|
|
4924
|
+
const coordinatorName = getCoordinatorName(employees);
|
|
4925
|
+
if (isCoordinatorName(String(row.assigned_to), employees)) return;
|
|
4926
|
+
if (String(row.title).startsWith("Review:")) return;
|
|
4927
|
+
const fileName = taskFile.split("/").pop() ?? "";
|
|
4928
|
+
if (fileName.startsWith("review-") && String(row.assigned_by) === "system") return;
|
|
4929
|
+
if (fileName.startsWith("review-") && String(row.assigned_to) === "system") return;
|
|
4930
|
+
const client = getClient();
|
|
4931
|
+
const agent = String(row.assigned_to);
|
|
4932
|
+
const rawReviewer = row.reviewer || row.assigned_by;
|
|
4933
|
+
const reviewer = rawReviewer ? String(rawReviewer) : coordinatorName;
|
|
4934
|
+
const currentStatus = String(row.status ?? "");
|
|
4935
|
+
if (currentStatus === "done") return;
|
|
4936
|
+
const existingResult = String(row.result ?? "");
|
|
4937
|
+
if (existingResult.includes("## Review notes")) return;
|
|
4938
|
+
let reviewerRole = "unknown";
|
|
4939
|
+
try {
|
|
4940
|
+
const emp = getEmployee(employees, reviewer);
|
|
4941
|
+
if (emp) reviewerRole = emp.role;
|
|
4942
|
+
} catch {
|
|
4943
|
+
}
|
|
4944
|
+
const taskTitle = String(row.title);
|
|
4945
|
+
const taskSlug = taskFile.split("/").pop()?.replace(".md", "") ?? "unknown";
|
|
4946
|
+
const { lens, checklist } = getReviewChecklist(reviewerRole, agent, taskSlug);
|
|
4947
|
+
process.stderr.write(
|
|
4948
|
+
`[review] Annotating "${taskTitle}" for review by ${reviewer} (${reviewerRole})
|
|
4949
|
+
`
|
|
4950
|
+
);
|
|
4951
|
+
const reviewNotes = [
|
|
4952
|
+
`
|
|
4953
|
+
---
|
|
4954
|
+
## Review notes`,
|
|
4955
|
+
`Review lens: ${lens}`,
|
|
4956
|
+
`Reviewer: **${reviewer}** (${reviewerRole})`,
|
|
4957
|
+
"",
|
|
4958
|
+
"### Checklist",
|
|
4959
|
+
...checklist,
|
|
4960
|
+
"",
|
|
4961
|
+
"### Verdict",
|
|
4962
|
+
"- **Approved:** mark this task as done",
|
|
4963
|
+
"- **Needs work:** re-open with notes"
|
|
4964
|
+
].join("\n");
|
|
4965
|
+
const originalTaskId = String(row.id);
|
|
4966
|
+
const updatedResult = (result ?? "No result summary provided") + reviewNotes;
|
|
4967
|
+
await client.execute({
|
|
4968
|
+
sql: `UPDATE tasks SET result = ?, status = 'needs_review', updated_at = ?
|
|
4969
|
+
WHERE id = ?`,
|
|
4970
|
+
args: [updatedResult, now, originalTaskId]
|
|
4971
|
+
});
|
|
4972
|
+
orgBus.emit({
|
|
4973
|
+
type: "review_created",
|
|
4974
|
+
reviewId: originalTaskId,
|
|
4975
|
+
employee: agent,
|
|
4976
|
+
reviewer,
|
|
4977
|
+
timestamp: now
|
|
4978
|
+
});
|
|
4979
|
+
await writeNotification({
|
|
4980
|
+
agentId: agent,
|
|
4981
|
+
agentRole: String(row.assigned_to),
|
|
4982
|
+
event: "task_complete",
|
|
4983
|
+
project: String(row.project_name),
|
|
4984
|
+
summary: `completed "${taskTitle}" \u2014 ready for review`,
|
|
4985
|
+
taskFile
|
|
4986
|
+
});
|
|
4987
|
+
const originalPriority = String(row.priority).toLowerCase();
|
|
4988
|
+
const autoApprove = originalPriority === "p2" && result?.toLowerCase().includes("tests pass");
|
|
4989
|
+
if (!autoApprove) {
|
|
4990
|
+
try {
|
|
4991
|
+
const key = getSessionKey();
|
|
4992
|
+
const exeSession = getParentExe(key);
|
|
4993
|
+
if (exeSession) {
|
|
4994
|
+
sendIntercom(exeSession);
|
|
4995
|
+
}
|
|
4996
|
+
} catch {
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
if (autoApprove) {
|
|
5000
|
+
process.stderr.write(
|
|
5001
|
+
`[review] Auto-approving "${taskTitle}" (P2 + tests pass)
|
|
5002
|
+
`
|
|
5003
|
+
);
|
|
5004
|
+
await client.execute({
|
|
5005
|
+
sql: "UPDATE tasks SET status = 'done', updated_at = ? WHERE id = ?",
|
|
5006
|
+
args: [now, originalTaskId]
|
|
5007
|
+
});
|
|
5008
|
+
}
|
|
5009
|
+
}
|
|
4894
5010
|
async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
4895
5011
|
if (String(row.assigned_by) !== "system" || !taskFile.includes("review-")) return;
|
|
4896
5012
|
try {
|
|
@@ -6254,15 +6370,17 @@ function sendIntercom(targetSession) {
|
|
|
6254
6370
|
logIntercom(`QUEUED \u2192 ${targetSession} (session busy)${batched2 > 0 ? ` [${batched2} batched]` : ""}`);
|
|
6255
6371
|
return "queued";
|
|
6256
6372
|
}
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6373
|
+
if (sessionState !== "idle") {
|
|
6374
|
+
try {
|
|
6375
|
+
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
6376
|
+
const agent = baseAgentName(rawAgent);
|
|
6377
|
+
const markerPath = path17.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
6378
|
+
if (existsSync15(markerPath)) {
|
|
6379
|
+
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
|
|
6380
|
+
return "debounced";
|
|
6381
|
+
}
|
|
6382
|
+
} catch {
|
|
6264
6383
|
}
|
|
6265
|
-
} catch {
|
|
6266
6384
|
}
|
|
6267
6385
|
try {
|
|
6268
6386
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
@@ -6333,6 +6451,24 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6333
6451
|
try {
|
|
6334
6452
|
const sessions = transport.listSessions();
|
|
6335
6453
|
if (!sessions.includes(coordinatorSession)) return false;
|
|
6454
|
+
try {
|
|
6455
|
+
const { countPendingReviews: countPendingReviews2 } = (init_tasks_review(), __toCommonJS(tasks_review_exports));
|
|
6456
|
+
const pending = countPendingReviews2(coordinatorSession);
|
|
6457
|
+
if (pending instanceof Promise) {
|
|
6458
|
+
pending.then((count) => {
|
|
6459
|
+
if (count > 0) {
|
|
6460
|
+
execSync7(
|
|
6461
|
+
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6462
|
+
{ timeout: 3e3 }
|
|
6463
|
+
);
|
|
6464
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6465
|
+
}
|
|
6466
|
+
}).catch(() => {
|
|
6467
|
+
});
|
|
6468
|
+
return true;
|
|
6469
|
+
}
|
|
6470
|
+
} catch {
|
|
6471
|
+
}
|
|
6336
6472
|
execSync7(
|
|
6337
6473
|
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6338
6474
|
{ timeout: 3e3 }
|
package/package.json
CHANGED