@askexenow/exe-os 0.9.4 → 0.9.6

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.
@@ -6624,7 +6624,7 @@ __export(tmux_routing_exports, {
6624
6624
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
6625
6625
  });
6626
6626
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
6627
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7, existsSync as existsSync14, appendFileSync } from "fs";
6627
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7, existsSync as existsSync14, appendFileSync, readdirSync as readdirSync5 } from "fs";
6628
6628
  import path18 from "path";
6629
6629
  import os8 from "os";
6630
6630
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -6945,6 +6945,24 @@ function sendIntercom(targetSession) {
6945
6945
  }
6946
6946
  } catch {
6947
6947
  }
6948
+ try {
6949
+ const rawAgent = targetSession.split("-")[0] ?? targetSession;
6950
+ const agent = baseAgentName(rawAgent);
6951
+ const taskDir = path18.join(process.cwd(), "exe", agent);
6952
+ if (existsSync14(taskDir)) {
6953
+ const files = readdirSync5(taskDir).filter(
6954
+ (f) => f.endsWith(".md") && f !== "DONE.txt"
6955
+ );
6956
+ if (files.length === 0) {
6957
+ logIntercom(`SKIP \u2192 ${targetSession} (no task files in exe/${agent}/ \u2014 nothing to do)`);
6958
+ return "debounced";
6959
+ }
6960
+ } else {
6961
+ logIntercom(`SKIP \u2192 ${targetSession} (no task folder exe/${agent}/ \u2014 nothing to do)`);
6962
+ return "debounced";
6963
+ }
6964
+ } catch {
6965
+ }
6948
6966
  if (transport.isPaneInCopyMode(targetSession)) {
6949
6967
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
6950
6968
  transport.sendKeys(targetSession, "q");
@@ -7982,7 +8000,7 @@ var init_tasks_crud = __esm({
7982
8000
 
7983
8001
  // src/lib/tasks-review.ts
7984
8002
  import path20 from "path";
7985
- import { existsSync as existsSync16, readdirSync as readdirSync5, unlinkSync as unlinkSync6 } from "fs";
8003
+ import { existsSync as existsSync16, readdirSync as readdirSync6, unlinkSync as unlinkSync6 } from "fs";
7986
8004
  async function countPendingReviews(sessionScope) {
7987
8005
  const client = getClient();
7988
8006
  if (sessionScope) {
@@ -8165,7 +8183,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
8165
8183
  try {
8166
8184
  const cacheDir = path20.join(EXE_AI_DIR, "session-cache");
8167
8185
  if (existsSync16(cacheDir)) {
8168
- for (const f of readdirSync5(cacheDir)) {
8186
+ for (const f of readdirSync6(cacheDir)) {
8169
8187
  if (f.startsWith("review-notified-")) {
8170
8188
  unlinkSync6(path20.join(cacheDir, f));
8171
8189
  }
@@ -8950,7 +8968,7 @@ __export(identity_exports, {
8950
8968
  updateIdentity: () => updateIdentity
8951
8969
  });
8952
8970
  import { existsSync as existsSync17, mkdirSync as mkdirSync9, readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "fs";
8953
- import { readdirSync as readdirSync6 } from "fs";
8971
+ import { readdirSync as readdirSync7 } from "fs";
8954
8972
  import path23 from "path";
8955
8973
  import { createHash as createHash2 } from "crypto";
8956
8974
  function ensureDir2() {
@@ -9032,7 +9050,7 @@ async function updateIdentity(agentId, content, updatedBy) {
9032
9050
  }
9033
9051
  function listIdentities() {
9034
9052
  ensureDir2();
9035
- const files = readdirSync6(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
9053
+ const files = readdirSync7(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
9036
9054
  const results = [];
9037
9055
  for (const file of files) {
9038
9056
  const agentId = file.replace(".md", "");
@@ -10327,7 +10345,7 @@ __export(worker_gate_exports, {
10327
10345
  tryAcquireBackfillLock: () => tryAcquireBackfillLock,
10328
10346
  tryAcquireWorkerSlot: () => tryAcquireWorkerSlot
10329
10347
  });
10330
- import { readdirSync as readdirSync9, writeFileSync as writeFileSync17, unlinkSync as unlinkSync8, mkdirSync as mkdirSync14, existsSync as existsSync25 } from "fs";
10348
+ import { readdirSync as readdirSync10, writeFileSync as writeFileSync17, unlinkSync as unlinkSync8, mkdirSync as mkdirSync14, existsSync as existsSync25 } from "fs";
10331
10349
  import path33 from "path";
10332
10350
  function tryAcquireWorkerSlot() {
10333
10351
  try {
@@ -10335,7 +10353,7 @@ function tryAcquireWorkerSlot() {
10335
10353
  const reservationId = `res-${process.pid}-${Date.now()}`;
10336
10354
  const reservationPath = path33.join(WORKER_PID_DIR, `${reservationId}.pid`);
10337
10355
  writeFileSync17(reservationPath, String(process.pid));
10338
- const files = readdirSync9(WORKER_PID_DIR);
10356
+ const files = readdirSync10(WORKER_PID_DIR);
10339
10357
  let alive = 0;
10340
10358
  for (const f of files) {
10341
10359
  if (!f.endsWith(".pid")) continue;
@@ -11287,6 +11305,8 @@ ${typeBreakdown}`
11287
11305
  init_tasks();
11288
11306
  init_active_agent();
11289
11307
  init_tmux_routing();
11308
+ init_employees();
11309
+ init_plan_limits();
11290
11310
  import { z as z7 } from "zod";
11291
11311
  function registerCreateTask(server2) {
11292
11312
  server2.registerTool(
@@ -11309,6 +11329,18 @@ function registerCreateTask(server2) {
11309
11329
  }
11310
11330
  },
11311
11331
  async ({ title, assigned_to, project_name, priority, complexity, context, blocked_by, parent_task_id, reviewer, budget_tokens, budget_fallback_model }) => {
11332
+ if (!isCoordinatorName(assigned_to)) {
11333
+ const license = getLicenseSync();
11334
+ if (license.plan === "free") {
11335
+ return {
11336
+ content: [{
11337
+ type: "text",
11338
+ text: "Upgrade to hire specialists. Free plan includes your COO only. Get a license at https://askexe.com"
11339
+ }],
11340
+ isError: true
11341
+ };
11342
+ }
11343
+ }
11312
11344
  const { agentId: assignedBy } = getActiveAgent();
11313
11345
  const task = await createTask({
11314
11346
  title,
@@ -13482,14 +13514,14 @@ function registerListTriggers(server2) {
13482
13514
  import { z as z31 } from "zod";
13483
13515
 
13484
13516
  // src/automation/starter-packs/index.ts
13485
- import { readFileSync as readFileSync17, readdirSync as readdirSync7, existsSync as existsSync19 } from "fs";
13517
+ import { readFileSync as readFileSync17, readdirSync as readdirSync8, existsSync as existsSync19 } from "fs";
13486
13518
  import path25 from "path";
13487
13519
  import { fileURLToPath as fileURLToPath3 } from "url";
13488
13520
  var __dirname = path25.dirname(fileURLToPath3(import.meta.url));
13489
13521
  function listPacks() {
13490
13522
  const packsDir = path25.join(__dirname, ".");
13491
13523
  if (!existsSync19(packsDir)) return [];
13492
- return readdirSync7(packsDir, { withFileTypes: true }).filter(
13524
+ return readdirSync8(packsDir, { withFileTypes: true }).filter(
13493
13525
  (d) => d.isDirectory() && existsSync19(path25.join(packsDir, d.name, "custom-objects.json"))
13494
13526
  ).map((d) => d.name);
13495
13527
  }
@@ -13521,7 +13553,7 @@ function loadPack(industry) {
13521
13553
  }
13522
13554
  const wikiSeeds = [];
13523
13555
  if (existsSync19(wikiDir)) {
13524
- const files = readdirSync7(wikiDir).filter((f) => f.endsWith(".md"));
13556
+ const files = readdirSync8(wikiDir).filter((f) => f.endsWith(".md"));
13525
13557
  for (const file of files) {
13526
13558
  const content = readFileSync17(path25.join(wikiDir, file), "utf-8");
13527
13559
  const titleMatch = content.match(/^#\s+(.+)/m);
@@ -15641,13 +15673,13 @@ function registerQueryConversations(server2) {
15641
15673
 
15642
15674
  // src/mcp/tools/load-skill.ts
15643
15675
  import { z as z41 } from "zod";
15644
- import { readFileSync as readFileSync20, readdirSync as readdirSync8, statSync as statSync3 } from "fs";
15676
+ import { readFileSync as readFileSync20, readdirSync as readdirSync9, statSync as statSync3 } from "fs";
15645
15677
  import path30 from "path";
15646
15678
  import { homedir as homedir2 } from "os";
15647
15679
  var SKILLS_DIR = path30.join(homedir2(), ".claude", "skills");
15648
15680
  function listAvailableSkills() {
15649
15681
  try {
15650
- const entries = readdirSync8(SKILLS_DIR);
15682
+ const entries = readdirSync9(SKILLS_DIR);
15651
15683
  return entries.filter((entry) => {
15652
15684
  try {
15653
15685
  const entryPath = path30.join(SKILLS_DIR, entry);
@@ -17393,7 +17425,7 @@ function registerGetAutoWakeStatus(server2) {
17393
17425
  init_worker_gate();
17394
17426
  init_config();
17395
17427
  import { z as z58 } from "zod";
17396
- import { readdirSync as readdirSync10, existsSync as existsSync26 } from "fs";
17428
+ import { readdirSync as readdirSync11, existsSync as existsSync26 } from "fs";
17397
17429
  import path34 from "path";
17398
17430
  var WORKER_PID_DIR2 = path34.join(EXE_AI_DIR, "worker-pids");
17399
17431
  function countAliveWorkers() {
@@ -17402,7 +17434,7 @@ function countAliveWorkers() {
17402
17434
  let reservations = 0;
17403
17435
  try {
17404
17436
  if (!existsSync26(WORKER_PID_DIR2)) return { alive: 0, stale: 0, reservations: 0 };
17405
- const files = readdirSync10(WORKER_PID_DIR2);
17437
+ const files = readdirSync11(WORKER_PID_DIR2);
17406
17438
  for (const f of files) {
17407
17439
  if (!f.endsWith(".pid")) continue;
17408
17440
  if (f.startsWith("res-")) {
@@ -18308,7 +18340,7 @@ import { z as z60 } from "zod";
18308
18340
 
18309
18341
  // src/lib/cloud-sync.ts
18310
18342
  init_database();
18311
- import { readFileSync as readFileSync25, writeFileSync as writeFileSync19, existsSync as existsSync29, readdirSync as readdirSync11, mkdirSync as mkdirSync16, appendFileSync as appendFileSync2, unlinkSync as unlinkSync10, openSync as openSync2, closeSync as closeSync2 } from "fs";
18343
+ import { readFileSync as readFileSync25, writeFileSync as writeFileSync19, existsSync as existsSync29, readdirSync as readdirSync12, mkdirSync as mkdirSync16, appendFileSync as appendFileSync2, unlinkSync as unlinkSync10, openSync as openSync2, closeSync as closeSync2 } from "fs";
18312
18344
  import crypto16 from "crypto";
18313
18345
  import path37 from "path";
18314
18346
  import { homedir as homedir6 } from "os";
@@ -18786,7 +18818,7 @@ async function cloudSync(config2) {
18786
18818
  rosterResult.employees = employees.length;
18787
18819
  const idDir = path37.join(EXE_AI_DIR, "identity");
18788
18820
  if (existsSync29(idDir)) {
18789
- rosterResult.identities = readdirSync11(idDir).filter((f) => f.endsWith(".md")).length;
18821
+ rosterResult.identities = readdirSync12(idDir).filter((f) => f.endsWith(".md")).length;
18790
18822
  }
18791
18823
  } catch {
18792
18824
  }
@@ -18827,7 +18859,7 @@ function buildRosterBlob(paths) {
18827
18859
  }
18828
18860
  const identities = {};
18829
18861
  if (existsSync29(identityDir)) {
18830
- for (const file of readdirSync11(identityDir).filter((f) => f.endsWith(".md"))) {
18862
+ for (const file of readdirSync12(identityDir).filter((f) => f.endsWith(".md"))) {
18831
18863
  try {
18832
18864
  identities[file] = readFileSync25(path37.join(identityDir, file), "utf-8");
18833
18865
  } catch {
@@ -1525,7 +1525,7 @@ __export(tmux_routing_exports, {
1525
1525
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
1526
1526
  });
1527
1527
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
1528
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync9, appendFileSync } from "fs";
1528
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync9, appendFileSync, readdirSync as readdirSync2 } from "fs";
1529
1529
  import path9 from "path";
1530
1530
  import os6 from "os";
1531
1531
  import { fileURLToPath } from "url";
@@ -1846,6 +1846,24 @@ function sendIntercom(targetSession) {
1846
1846
  }
1847
1847
  } catch {
1848
1848
  }
1849
+ try {
1850
+ const rawAgent = targetSession.split("-")[0] ?? targetSession;
1851
+ const agent = baseAgentName(rawAgent);
1852
+ const taskDir = path9.join(process.cwd(), "exe", agent);
1853
+ if (existsSync9(taskDir)) {
1854
+ const files = readdirSync2(taskDir).filter(
1855
+ (f) => f.endsWith(".md") && f !== "DONE.txt"
1856
+ );
1857
+ if (files.length === 0) {
1858
+ logIntercom(`SKIP \u2192 ${targetSession} (no task files in exe/${agent}/ \u2014 nothing to do)`);
1859
+ return "debounced";
1860
+ }
1861
+ } else {
1862
+ logIntercom(`SKIP \u2192 ${targetSession} (no task folder exe/${agent}/ \u2014 nothing to do)`);
1863
+ return "debounced";
1864
+ }
1865
+ } catch {
1866
+ }
1849
1867
  if (transport.isPaneInCopyMode(targetSession)) {
1850
1868
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
1851
1869
  transport.sendKeys(targetSession, "q");
@@ -2867,7 +2885,7 @@ var init_tasks_crud = __esm({
2867
2885
 
2868
2886
  // src/lib/tasks-review.ts
2869
2887
  import path11 from "path";
2870
- import { existsSync as existsSync11, readdirSync as readdirSync2, unlinkSync as unlinkSync4 } from "fs";
2888
+ import { existsSync as existsSync11, readdirSync as readdirSync3, unlinkSync as unlinkSync4 } from "fs";
2871
2889
  async function countPendingReviews(sessionScope) {
2872
2890
  const client = getClient();
2873
2891
  if (sessionScope) {
@@ -3050,7 +3068,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
3050
3068
  try {
3051
3069
  const cacheDir = path11.join(EXE_AI_DIR, "session-cache");
3052
3070
  if (existsSync11(cacheDir)) {
3053
- for (const f of readdirSync2(cacheDir)) {
3071
+ for (const f of readdirSync3(cacheDir)) {
3054
3072
  if (f.startsWith("review-notified-")) {
3055
3073
  unlinkSync4(path11.join(cacheDir, f));
3056
3074
  }
@@ -3849,7 +3867,7 @@ __export(identity_exports, {
3849
3867
  updateIdentity: () => updateIdentity
3850
3868
  });
3851
3869
  import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
3852
- import { readdirSync as readdirSync4 } from "fs";
3870
+ import { readdirSync as readdirSync5 } from "fs";
3853
3871
  import path16 from "path";
3854
3872
  import { createHash } from "crypto";
3855
3873
  function ensureDir2() {
@@ -3931,7 +3949,7 @@ async function updateIdentity(agentId, content, updatedBy) {
3931
3949
  }
3932
3950
  function listIdentities() {
3933
3951
  ensureDir2();
3934
- const files = readdirSync4(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
3952
+ const files = readdirSync5(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
3935
3953
  const results = [];
3936
3954
  for (const file of files) {
3937
3955
  const agentId = file.replace(".md", "");
@@ -4523,7 +4541,7 @@ import { z } from "zod";
4523
4541
  init_config();
4524
4542
  init_session_key();
4525
4543
  init_employees();
4526
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, unlinkSync as unlinkSync6, readdirSync as readdirSync3 } from "fs";
4544
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, unlinkSync as unlinkSync6, readdirSync as readdirSync4 } from "fs";
4527
4545
  import { execSync as execSync7 } from "child_process";
4528
4546
  import path15 from "path";
4529
4547
  var CACHE_DIR = path15.join(EXE_AI_DIR, "session-cache");
@@ -4618,6 +4636,8 @@ function getActiveAgent() {
4618
4636
 
4619
4637
  // src/mcp/tools/create-task.ts
4620
4638
  init_tmux_routing();
4639
+ init_employees();
4640
+ init_plan_limits();
4621
4641
  function registerCreateTask(server) {
4622
4642
  server.registerTool(
4623
4643
  "create_task",
@@ -4639,6 +4659,18 @@ function registerCreateTask(server) {
4639
4659
  }
4640
4660
  },
4641
4661
  async ({ title, assigned_to, project_name, priority, complexity, context, blocked_by, parent_task_id, reviewer, budget_tokens, budget_fallback_model }) => {
4662
+ if (!isCoordinatorName(assigned_to)) {
4663
+ const license = getLicenseSync();
4664
+ if (license.plan === "free") {
4665
+ return {
4666
+ content: [{
4667
+ type: "text",
4668
+ text: "Upgrade to hire specialists. Free plan includes your COO only. Get a license at https://askexe.com"
4669
+ }],
4670
+ isError: true
4671
+ };
4672
+ }
4673
+ }
4642
4674
  const { agentId: assignedBy } = getActiveAgent();
4643
4675
  const task = await createTask({
4644
4676
  title,
@@ -535,7 +535,7 @@ var init_plan_limits = __esm({
535
535
  });
536
536
 
537
537
  // src/lib/tmux-routing.ts
538
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync } from "fs";
538
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync, readdirSync as readdirSync2 } from "fs";
539
539
  import path9 from "path";
540
540
  import os6 from "os";
541
541
  import { fileURLToPath } from "url";
@@ -705,7 +705,7 @@ var init_tasks_crud = __esm({
705
705
 
706
706
  // src/lib/tasks-review.ts
707
707
  import path11 from "path";
708
- import { existsSync as existsSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
708
+ import { existsSync as existsSync10, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
709
709
  var init_tasks_review = __esm({
710
710
  "src/lib/tasks-review.ts"() {
711
711
  "use strict";
@@ -548,7 +548,7 @@ var init_plan_limits = __esm({
548
548
 
549
549
  // src/lib/tmux-routing.ts
550
550
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
551
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync7, appendFileSync } from "fs";
551
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync7, appendFileSync, readdirSync } from "fs";
552
552
  import path8 from "path";
553
553
  import os5 from "os";
554
554
  import { fileURLToPath } from "url";
@@ -733,6 +733,24 @@ function sendIntercom(targetSession) {
733
733
  }
734
734
  } catch {
735
735
  }
736
+ try {
737
+ const rawAgent = targetSession.split("-")[0] ?? targetSession;
738
+ const agent = baseAgentName(rawAgent);
739
+ const taskDir = path8.join(process.cwd(), "exe", agent);
740
+ if (existsSync7(taskDir)) {
741
+ const files = readdirSync(taskDir).filter(
742
+ (f) => f.endsWith(".md") && f !== "DONE.txt"
743
+ );
744
+ if (files.length === 0) {
745
+ logIntercom(`SKIP \u2192 ${targetSession} (no task files in exe/${agent}/ \u2014 nothing to do)`);
746
+ return "debounced";
747
+ }
748
+ } else {
749
+ logIntercom(`SKIP \u2192 ${targetSession} (no task folder exe/${agent}/ \u2014 nothing to do)`);
750
+ return "debounced";
751
+ }
752
+ } catch {
753
+ }
736
754
  if (transport.isPaneInCopyMode(targetSession)) {
737
755
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
738
756
  transport.sendKeys(targetSession, "q");
@@ -933,7 +951,7 @@ async function markFailed(messageId, reason) {
933
951
  init_config();
934
952
  init_session_key();
935
953
  init_employees();
936
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, readdirSync } from "fs";
954
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, readdirSync as readdirSync2 } from "fs";
937
955
  import { execSync as execSync5 } from "child_process";
938
956
  import path9 from "path";
939
957
  var CACHE_DIR = path9.join(EXE_AI_DIR, "session-cache");
@@ -837,7 +837,7 @@ var init_plan_limits = __esm({
837
837
 
838
838
  // src/lib/tmux-routing.ts
839
839
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
840
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync } from "fs";
840
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync, readdirSync as readdirSync2 } from "fs";
841
841
  import path9 from "path";
842
842
  import os6 from "os";
843
843
  import { fileURLToPath } from "url";
@@ -1003,6 +1003,24 @@ function sendIntercom(targetSession) {
1003
1003
  }
1004
1004
  } catch {
1005
1005
  }
1006
+ try {
1007
+ const rawAgent = targetSession.split("-")[0] ?? targetSession;
1008
+ const agent = baseAgentName(rawAgent);
1009
+ const taskDir = path9.join(process.cwd(), "exe", agent);
1010
+ if (existsSync8(taskDir)) {
1011
+ const files = readdirSync2(taskDir).filter(
1012
+ (f) => f.endsWith(".md") && f !== "DONE.txt"
1013
+ );
1014
+ if (files.length === 0) {
1015
+ logIntercom(`SKIP \u2192 ${targetSession} (no task files in exe/${agent}/ \u2014 nothing to do)`);
1016
+ return "debounced";
1017
+ }
1018
+ } else {
1019
+ logIntercom(`SKIP \u2192 ${targetSession} (no task folder exe/${agent}/ \u2014 nothing to do)`);
1020
+ return "debounced";
1021
+ }
1022
+ } catch {
1023
+ }
1006
1024
  if (transport.isPaneInCopyMode(targetSession)) {
1007
1025
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
1008
1026
  transport.sendKeys(targetSession, "q");
@@ -1402,7 +1420,7 @@ var init_tasks_crud = __esm({
1402
1420
 
1403
1421
  // src/lib/tasks-review.ts
1404
1422
  import path11 from "path";
1405
- import { existsSync as existsSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
1423
+ import { existsSync as existsSync10, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
1406
1424
  async function cleanupReviewFile(row, taskFile, _baseDir) {
1407
1425
  if (String(row.assigned_by) !== "system" || !taskFile.includes("review-")) return;
1408
1426
  try {
@@ -1449,7 +1467,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
1449
1467
  try {
1450
1468
  const cacheDir = path11.join(EXE_AI_DIR, "session-cache");
1451
1469
  if (existsSync10(cacheDir)) {
1452
- for (const f of readdirSync2(cacheDir)) {
1470
+ for (const f of readdirSync3(cacheDir)) {
1453
1471
  if (f.startsWith("review-notified-")) {
1454
1472
  unlinkSync3(path11.join(cacheDir, f));
1455
1473
  }
@@ -2054,7 +2072,7 @@ __export(active_agent_exports, {
2054
2072
  resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
2055
2073
  writeActiveAgent: () => writeActiveAgent
2056
2074
  });
2057
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5, readdirSync as readdirSync3 } from "fs";
2075
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5, readdirSync as readdirSync4 } from "fs";
2058
2076
  import { execSync as execSync6 } from "child_process";
2059
2077
  import path14 from "path";
2060
2078
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -2162,7 +2180,7 @@ function getActiveAgent() {
2162
2180
  }
2163
2181
  function getAllActiveAgents() {
2164
2182
  try {
2165
- const files = readdirSync3(CACHE_DIR);
2183
+ const files = readdirSync4(CACHE_DIR);
2166
2184
  const sessions = [];
2167
2185
  for (const file of files) {
2168
2186
  if (!file.startsWith("active-agent-") || !file.endsWith(".json")) continue;
@@ -4513,7 +4513,7 @@ __export(tmux_routing_exports, {
4513
4513
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
4514
4514
  });
4515
4515
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
4516
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync } from "fs";
4516
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync, readdirSync as readdirSync3 } from "fs";
4517
4517
  import path16 from "path";
4518
4518
  import os9 from "os";
4519
4519
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -4834,6 +4834,24 @@ function sendIntercom(targetSession) {
4834
4834
  }
4835
4835
  } catch {
4836
4836
  }
4837
+ try {
4838
+ const rawAgent = targetSession.split("-")[0] ?? targetSession;
4839
+ const agent = baseAgentName(rawAgent);
4840
+ const taskDir = path16.join(process.cwd(), "exe", agent);
4841
+ if (existsSync12(taskDir)) {
4842
+ const files = readdirSync3(taskDir).filter(
4843
+ (f) => f.endsWith(".md") && f !== "DONE.txt"
4844
+ );
4845
+ if (files.length === 0) {
4846
+ logIntercom(`SKIP \u2192 ${targetSession} (no task files in exe/${agent}/ \u2014 nothing to do)`);
4847
+ return "debounced";
4848
+ }
4849
+ } else {
4850
+ logIntercom(`SKIP \u2192 ${targetSession} (no task folder exe/${agent}/ \u2014 nothing to do)`);
4851
+ return "debounced";
4852
+ }
4853
+ } catch {
4854
+ }
4837
4855
  if (transport.isPaneInCopyMode(targetSession)) {
4838
4856
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
4839
4857
  transport.sendKeys(targetSession, "q");
@@ -5320,7 +5338,7 @@ __export(shard_manager_exports, {
5320
5338
  shardExists: () => shardExists
5321
5339
  });
5322
5340
  import path18 from "path";
5323
- import { existsSync as existsSync14, mkdirSync as mkdirSync7, readdirSync as readdirSync3 } from "fs";
5341
+ import { existsSync as existsSync14, mkdirSync as mkdirSync7, readdirSync as readdirSync4 } from "fs";
5324
5342
  import { createClient as createClient2 } from "@libsql/client";
5325
5343
  function initShardManager(encryptionKey) {
5326
5344
  _encryptionKey = encryptionKey;
@@ -5359,7 +5377,7 @@ function shardExists(projectName) {
5359
5377
  }
5360
5378
  function listShards() {
5361
5379
  if (!existsSync14(SHARDS_DIR)) return [];
5362
- return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
5380
+ return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
5363
5381
  }
5364
5382
  async function ensureShardSchema(client) {
5365
5383
  await client.execute("PRAGMA journal_mode = WAL");
package/dist/tui/App.js CHANGED
@@ -5019,7 +5019,7 @@ __export(tmux_routing_exports, {
5019
5019
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
5020
5020
  });
5021
5021
  import { execFileSync as execFileSync3, execSync as execSync7 } from "child_process";
5022
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync13, appendFileSync } from "fs";
5022
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync13, appendFileSync, readdirSync as readdirSync3 } from "fs";
5023
5023
  import path15 from "path";
5024
5024
  import os8 from "os";
5025
5025
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -5340,6 +5340,24 @@ function sendIntercom(targetSession) {
5340
5340
  }
5341
5341
  } catch {
5342
5342
  }
5343
+ try {
5344
+ const rawAgent = targetSession.split("-")[0] ?? targetSession;
5345
+ const agent = baseAgentName(rawAgent);
5346
+ const taskDir = path15.join(process.cwd(), "exe", agent);
5347
+ if (existsSync13(taskDir)) {
5348
+ const files = readdirSync3(taskDir).filter(
5349
+ (f) => f.endsWith(".md") && f !== "DONE.txt"
5350
+ );
5351
+ if (files.length === 0) {
5352
+ logIntercom(`SKIP \u2192 ${targetSession} (no task files in exe/${agent}/ \u2014 nothing to do)`);
5353
+ return "debounced";
5354
+ }
5355
+ } else {
5356
+ logIntercom(`SKIP \u2192 ${targetSession} (no task folder exe/${agent}/ \u2014 nothing to do)`);
5357
+ return "debounced";
5358
+ }
5359
+ } catch {
5360
+ }
5343
5361
  if (transport.isPaneInCopyMode(targetSession)) {
5344
5362
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
5345
5363
  transport.sendKeys(targetSession, "q");
@@ -9274,7 +9292,7 @@ __export(shard_manager_exports, {
9274
9292
  shardExists: () => shardExists
9275
9293
  });
9276
9294
  import path25 from "path";
9277
- import { existsSync as existsSync15, mkdirSync as mkdirSync7, readdirSync as readdirSync3 } from "fs";
9295
+ import { existsSync as existsSync15, mkdirSync as mkdirSync7, readdirSync as readdirSync4 } from "fs";
9278
9296
  import { createClient as createClient2 } from "@libsql/client";
9279
9297
  function initShardManager(encryptionKey) {
9280
9298
  _encryptionKey = encryptionKey;
@@ -9313,7 +9331,7 @@ function shardExists(projectName) {
9313
9331
  }
9314
9332
  function listShards() {
9315
9333
  if (!existsSync15(SHARDS_DIR)) return [];
9316
- return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
9334
+ return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
9317
9335
  }
9318
9336
  async function ensureShardSchema(client) {
9319
9337
  await client.execute("PRAGMA journal_mode = WAL");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
5
5
  "license": "CC-BY-NC-4.0",
6
6
  "type": "module",