@agentmeshhq/agent 0.4.2 → 0.4.3

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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/dist/__tests__/evicted-cleanup.test.d.ts +10 -0
  3. package/dist/__tests__/evicted-cleanup.test.js +459 -0
  4. package/dist/__tests__/evicted-cleanup.test.js.map +1 -0
  5. package/dist/__tests__/local.test.d.ts +1 -0
  6. package/dist/__tests__/local.test.js +124 -0
  7. package/dist/__tests__/local.test.js.map +1 -0
  8. package/dist/__tests__/tmux-send.test.d.ts +10 -0
  9. package/dist/__tests__/tmux-send.test.js +96 -0
  10. package/dist/__tests__/tmux-send.test.js.map +1 -0
  11. package/dist/cli/inbox.d.ts +5 -0
  12. package/dist/cli/inbox.js +123 -0
  13. package/dist/cli/inbox.js.map +1 -0
  14. package/dist/cli/index.js +285 -11
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/issue.d.ts +42 -0
  17. package/dist/cli/issue.js +297 -0
  18. package/dist/cli/issue.js.map +1 -0
  19. package/dist/cli/local.d.ts +27 -6
  20. package/dist/cli/local.js +319 -36
  21. package/dist/cli/local.js.map +1 -1
  22. package/dist/cli/ready.d.ts +5 -0
  23. package/dist/cli/ready.js +131 -0
  24. package/dist/cli/ready.js.map +1 -0
  25. package/dist/cli/sync.d.ts +8 -0
  26. package/dist/cli/sync.js +154 -0
  27. package/dist/cli/sync.js.map +1 -0
  28. package/dist/cli/token.js +242 -9
  29. package/dist/cli/token.js.map +1 -1
  30. package/dist/cli/whoami.d.ts +6 -0
  31. package/dist/cli/whoami.js +109 -5
  32. package/dist/cli/whoami.js.map +1 -1
  33. package/dist/core/cleanup/eligibility.d.ts +41 -0
  34. package/dist/core/cleanup/eligibility.js +64 -0
  35. package/dist/core/cleanup/eligibility.js.map +1 -0
  36. package/dist/core/cleanup/scheduler.d.ts +50 -0
  37. package/dist/core/cleanup/scheduler.js +120 -0
  38. package/dist/core/cleanup/scheduler.js.map +1 -0
  39. package/dist/core/cleanup/worker.d.ts +63 -0
  40. package/dist/core/cleanup/worker.js +191 -0
  41. package/dist/core/cleanup/worker.js.map +1 -0
  42. package/dist/core/daemon.d.ts +1 -0
  43. package/dist/core/daemon.js +18 -0
  44. package/dist/core/daemon.js.map +1 -1
  45. package/dist/core/heartbeat.d.ts +6 -1
  46. package/dist/core/heartbeat.js +44 -39
  47. package/dist/core/heartbeat.js.map +1 -1
  48. package/dist/core/issue-cache.d.ts +44 -0
  49. package/dist/core/issue-cache.js +75 -0
  50. package/dist/core/issue-cache.js.map +1 -0
  51. package/dist/core/registry.d.ts +1 -0
  52. package/dist/core/registry.js +1 -0
  53. package/dist/core/registry.js.map +1 -1
  54. package/dist/core/token-lifecycle.d.ts +81 -0
  55. package/dist/core/token-lifecycle.js +210 -0
  56. package/dist/core/token-lifecycle.js.map +1 -0
  57. package/dist/core/token-lifecycle.test.d.ts +10 -0
  58. package/dist/core/token-lifecycle.test.js +309 -0
  59. package/dist/core/token-lifecycle.test.js.map +1 -0
  60. package/package.json +11 -12
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.test.js","sourceRoot":"","sources":["../../src/__tests__/local.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tests for sendKeys helper in core/tmux.ts
3
+ *
4
+ * sendKeys(agentName, message):
5
+ * - returns false if session does not exist
6
+ * - sends literal keys and Enter when session exists
7
+ * - collapses newlines to " | " before sending
8
+ * - returns false (and logs) when execFileSync throws
9
+ */
10
+ export {};
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Tests for sendKeys helper in core/tmux.ts
3
+ *
4
+ * sendKeys(agentName, message):
5
+ * - returns false if session does not exist
6
+ * - sends literal keys and Enter when session exists
7
+ * - collapses newlines to " | " before sending
8
+ * - returns false (and logs) when execFileSync throws
9
+ */
10
+ import { execFileSync, execSync } from "node:child_process";
11
+ import { beforeEach, describe, expect, it, vi } from "vitest";
12
+ import { sendKeys } from "../core/tmux.js";
13
+ vi.mock("node:child_process", () => ({
14
+ execSync: vi.fn(),
15
+ execFileSync: vi.fn(),
16
+ spawn: vi.fn(),
17
+ }));
18
+ const mockExecSync = vi.mocked(execSync);
19
+ const mockExecFileSync = vi.mocked(execFileSync);
20
+ const SESSION_NAME = "agentmesh-test-agent";
21
+ describe("sendKeys", () => {
22
+ beforeEach(() => {
23
+ vi.resetAllMocks();
24
+ });
25
+ it("returns false when the tmux session does not exist", () => {
26
+ // sessionExists → execSync throws → returns false
27
+ mockExecSync.mockImplementation(() => {
28
+ throw new Error("no server running");
29
+ });
30
+ const result = sendKeys("test-agent", "hello");
31
+ expect(result).toBe(false);
32
+ expect(mockExecFileSync).not.toHaveBeenCalled();
33
+ });
34
+ it("sends the message literally and presses Enter when session exists", () => {
35
+ // sessionExists → execSync succeeds
36
+ mockExecSync.mockReturnValue(undefined);
37
+ mockExecFileSync.mockReturnValue(undefined);
38
+ const result = sendKeys("test-agent", "pnpm test");
39
+ expect(result).toBe(true);
40
+ // First call: send-keys -l <message>
41
+ expect(mockExecFileSync).toHaveBeenNthCalledWith(1, "tmux", [
42
+ "send-keys",
43
+ "-t",
44
+ SESSION_NAME,
45
+ "-l",
46
+ "pnpm test",
47
+ ]);
48
+ // Second call: send Enter
49
+ expect(mockExecFileSync).toHaveBeenNthCalledWith(2, "tmux", [
50
+ "send-keys",
51
+ "-t",
52
+ SESSION_NAME,
53
+ "Enter",
54
+ ]);
55
+ });
56
+ it("replaces newlines with ' | ' before sending", () => {
57
+ mockExecSync.mockReturnValue(undefined);
58
+ mockExecFileSync.mockReturnValue(undefined);
59
+ sendKeys("test-agent", "line one\nline two\nline three");
60
+ expect(mockExecFileSync).toHaveBeenNthCalledWith(1, "tmux", [
61
+ "send-keys",
62
+ "-t",
63
+ SESSION_NAME,
64
+ "-l",
65
+ "line one | line two | line three",
66
+ ]);
67
+ });
68
+ it("returns false when execFileSync throws (e.g. tmux error)", () => {
69
+ mockExecSync.mockReturnValue(undefined); // session exists
70
+ mockExecFileSync.mockImplementation(() => {
71
+ throw new Error("tmux: send-keys failed");
72
+ });
73
+ const result = sendKeys("test-agent", "some command");
74
+ expect(result).toBe(false);
75
+ });
76
+ it("sends an empty string message without error", () => {
77
+ mockExecSync.mockReturnValue(undefined);
78
+ mockExecFileSync.mockReturnValue(undefined);
79
+ const result = sendKeys("test-agent", "");
80
+ expect(result).toBe(true);
81
+ expect(mockExecFileSync).toHaveBeenNthCalledWith(1, "tmux", [
82
+ "send-keys",
83
+ "-t",
84
+ SESSION_NAME,
85
+ "-l",
86
+ "",
87
+ ]);
88
+ });
89
+ it("uses correct session name prefix (agentmesh-<agentName>)", () => {
90
+ mockExecSync.mockReturnValue(undefined);
91
+ mockExecFileSync.mockReturnValue(undefined);
92
+ sendKeys("my-special-agent", "test");
93
+ expect(mockExecFileSync).toHaveBeenCalledWith("tmux", expect.arrayContaining(["-t", "agentmesh-my-special-agent"]));
94
+ });
95
+ });
96
+ //# sourceMappingURL=tmux-send.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux-send.test.js","sourceRoot":"","sources":["../../src/__tests__/tmux-send.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IACnC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;IACjB,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;IACrB,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;CACf,CAAC,CAAC,CAAC;AAEJ,MAAM,YAAY,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACzC,MAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AAEjD,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAE5C,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,kDAAkD;QAClD,YAAY,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACnC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAE/C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,oCAAoC;QACpC,YAAY,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAC/C,gBAAgB,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,qCAAqC;QACrC,MAAM,CAAC,gBAAgB,CAAC,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE;YAC1D,WAAW;YACX,IAAI;YACJ,YAAY;YACZ,IAAI;YACJ,WAAW;SACZ,CAAC,CAAC;QACH,0BAA0B;QAC1B,MAAM,CAAC,gBAAgB,CAAC,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE;YAC1D,WAAW;YACX,IAAI;YACJ,YAAY;YACZ,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,YAAY,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAC/C,gBAAgB,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAEnD,QAAQ,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC;QAEzD,MAAM,CAAC,gBAAgB,CAAC,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE;YAC1D,WAAW;YACX,IAAI;YACJ,YAAY;YACZ,IAAI;YACJ,kCAAkC;SACnC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,YAAY,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC,CAAC,iBAAiB;QACjE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACvC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QAEtD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,YAAY,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAC/C,gBAAgB,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,gBAAgB,CAAC,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE;YAC1D,WAAW;YACX,IAAI;YACJ,YAAY;YACZ,IAAI;YACJ,EAAE;SACH,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,YAAY,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAC/C,gBAAgB,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAC;QAEnD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QAErC,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,MAAM,EACN,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAC7D,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Inbox CLI Command
3
+ * Shows agent's assigned issues and pending handoffs
4
+ */
5
+ export declare function inbox(): Promise<void>;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Inbox CLI Command
3
+ * Shows agent's assigned issues and pending handoffs
4
+ */
5
+ import pc from "picocolors";
6
+ import { getAgentState, loadConfig } from "../config/loader.js";
7
+ import { loadCache } from "../core/issue-cache.js";
8
+ async function getHubUrl() {
9
+ const config = loadConfig();
10
+ return config?.hubUrl || process.env.AGENTMESH_HUB_URL || "https://agentmeshhq.dev";
11
+ }
12
+ async function getToken() {
13
+ const state = getAgentState(process.env.AGENT_NAME || "");
14
+ if (state?.token)
15
+ return state.token;
16
+ if (process.env.AGENT_TOKEN)
17
+ return process.env.AGENT_TOKEN;
18
+ return null;
19
+ }
20
+ async function getWorkspace() {
21
+ const config = loadConfig();
22
+ return config?.workspace || process.env.AGENTMESH_WORKSPACE || "agentmesh";
23
+ }
24
+ async function apiRequest(path) {
25
+ const hubUrl = await getHubUrl();
26
+ const token = await getToken();
27
+ try {
28
+ const response = await fetch(`${hubUrl}${path}`, {
29
+ headers: {
30
+ "Content-Type": "application/json",
31
+ ...(token && { Authorization: `Bearer ${token}` }),
32
+ },
33
+ });
34
+ if (!response.ok) {
35
+ const error = await response.json().catch(() => ({ error: response.statusText }));
36
+ return { error: error.error || response.statusText };
37
+ }
38
+ const data = await response.json();
39
+ return { data: data };
40
+ }
41
+ catch (err) {
42
+ return { error: err.message };
43
+ }
44
+ }
45
+ function _getStatusColor(status) {
46
+ switch (status) {
47
+ case "open":
48
+ return pc.yellow;
49
+ case "in_progress":
50
+ return pc.blue;
51
+ case "review":
52
+ return pc.magenta;
53
+ case "closed":
54
+ return pc.green;
55
+ default:
56
+ return pc.dim;
57
+ }
58
+ }
59
+ function getPriorityColor(priority) {
60
+ switch (priority) {
61
+ case "P0":
62
+ return pc.red;
63
+ case "P1":
64
+ return (s) => pc.yellow(pc.bold(s));
65
+ case "P2":
66
+ return pc.yellow;
67
+ default:
68
+ return pc.dim;
69
+ }
70
+ }
71
+ export async function inbox() {
72
+ console.log(pc.bold("Your Inbox"));
73
+ console.log();
74
+ // Fetch issues assigned to me
75
+ const issuesResult = await apiRequest("/api/v1/agents/me/inbox");
76
+ if (issuesResult.error) {
77
+ if (issuesResult.error.includes("fetch") || issuesResult.error.includes("network")) {
78
+ console.log(pc.yellow("Offline - showing cached assigned issues"));
79
+ const workspace = await getWorkspace();
80
+ const cache = loadCache(workspace);
81
+ const state = getAgentState(process.env.AGENT_NAME || "");
82
+ const myIssues = cache.issues.filter((i) => i.assignee_agent_id === state?.agentId && i.status !== "closed");
83
+ displayInbox(myIssues);
84
+ return;
85
+ }
86
+ console.error(pc.red(`Error fetching inbox: ${issuesResult.error}`));
87
+ process.exit(1);
88
+ }
89
+ displayInbox(issuesResult.data?.issues || []);
90
+ }
91
+ function displayInbox(issues) {
92
+ if (issues.length === 0) {
93
+ console.log(pc.dim("No assigned issues. Use 'agentmesh ready' to find available work."));
94
+ return;
95
+ }
96
+ // Group by status
97
+ const inProgress = issues.filter((i) => i.status === "in_progress");
98
+ const review = issues.filter((i) => i.status === "review");
99
+ const open = issues.filter((i) => i.status === "open");
100
+ if (inProgress.length > 0) {
101
+ console.log(pc.blue(pc.bold("In Progress")));
102
+ for (const issue of inProgress) {
103
+ console.log(` ${pc.cyan(issue.issue_id)} ${getPriorityColor(issue.priority)(issue.priority)} ${issue.title}`);
104
+ }
105
+ console.log();
106
+ }
107
+ if (review.length > 0) {
108
+ console.log(pc.magenta(pc.bold("In Review")));
109
+ for (const issue of review) {
110
+ console.log(` ${pc.cyan(issue.issue_id)} ${getPriorityColor(issue.priority)(issue.priority)} ${issue.title}`);
111
+ }
112
+ console.log();
113
+ }
114
+ if (open.length > 0) {
115
+ console.log(pc.yellow(pc.bold("Open")));
116
+ for (const issue of open) {
117
+ console.log(` ${pc.cyan(issue.issue_id)} ${getPriorityColor(issue.priority)(issue.priority)} ${issue.title}`);
118
+ }
119
+ console.log();
120
+ }
121
+ console.log(pc.dim(`Total: ${issues.length} issue(s) assigned to you`));
122
+ }
123
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/cli/inbox.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -11,19 +11,22 @@ import { contextCmd } from "./context.js";
11
11
  import { deploy } from "./deploy.js";
12
12
  import { completeHandoff, inbox, reassignHandoff, updateHandoffStatus } from "./handoff.js";
13
13
  import { init } from "./init.js";
14
+ import { claimIssue, closeIssue, createIssue, handoffIssue, listIssues, showIssue, updateIssue, } from "./issue.js";
14
15
  import { list } from "./list.js";
15
- import { localDown, localLogs, localStatus, localUp } from "./local.js";
16
+ import { localDoctor, localDown, localLogs, localSmoke, localStatus, localUp } from "./local.js";
16
17
  import { logs } from "./logs.js";
17
18
  import { migrate } from "./migrate.js";
18
19
  import { nudge } from "./nudge.js";
20
+ import { ready } from "./ready.js";
19
21
  import { restart } from "./restart.js";
20
22
  import { slack } from "./slack.js";
21
23
  import { start } from "./start.js";
22
24
  import { status } from "./status.js";
23
25
  import { stop } from "./stop.js";
26
+ import { sync } from "./sync.js";
24
27
  import { test } from "./test.js";
25
28
  import { token } from "./token.js";
26
- import { whoami } from "./whoami.js";
29
+ import { resolvePO, whoami } from "./whoami.js";
27
30
  import { pauseWorkerAutomation, resumeWorkerAutomation } from "./worker.js";
28
31
  const require = createRequire(import.meta.url);
29
32
  const pkg = require("../../package.json");
@@ -314,9 +317,29 @@ program
314
317
  .command("whoami")
315
318
  .description("Show current agent identity and status")
316
319
  .argument("[name]", "Agent name (optional)")
317
- .action(async (name) => {
320
+ .option("--po", "Resolve and print the canonical Product Owner agent ID for this team")
321
+ .action(async (name, options) => {
322
+ try {
323
+ if (options.po) {
324
+ await resolvePO(name);
325
+ }
326
+ else {
327
+ await whoami(name);
328
+ }
329
+ }
330
+ catch (error) {
331
+ console.error(pc.red(error.message));
332
+ process.exit(1);
333
+ }
334
+ });
335
+ const poCmd = program.command("po").description("Product Owner operations");
336
+ poCmd
337
+ .command("resolve")
338
+ .description("Resolve the canonical Product Owner agent ID for the current team/workspace")
339
+ .option("-n, --name <name>", "Agent name (for token resolution)")
340
+ .action(async (options) => {
318
341
  try {
319
- await whoami(name);
342
+ await resolvePO(options.name);
320
343
  }
321
344
  catch (error) {
322
345
  console.error(pc.red(error.message));
@@ -326,7 +349,7 @@ program
326
349
  program
327
350
  .command("token")
328
351
  .description("Manage agent tokens")
329
- .argument("[action]", "Action: show (default), refresh, info")
352
+ .argument("[action]", "Action: show (default), refresh, info, health")
330
353
  .option("-n, --name <name>", "Agent name")
331
354
  .action(async (action, options) => {
332
355
  try {
@@ -460,9 +483,17 @@ localCmd
460
483
  .command("up")
461
484
  .description("Start local development stack")
462
485
  .option("--no-detach", "Run in foreground")
486
+ .option("--target <path>", "Compose file path or target name (default: docker/docker-compose.local.yml)")
487
+ .option("--slot <number>", "Slot number for deterministic non-overlapping port block (0-based)", parseInt)
488
+ .option("--project <name>", "Docker Compose project name for namespace isolation")
463
489
  .action(async (options) => {
464
490
  try {
465
- await localUp({ detach: options.detach });
491
+ await localUp({
492
+ detach: options.detach,
493
+ target: options.target,
494
+ slot: options.slot,
495
+ project: options.project,
496
+ });
466
497
  }
467
498
  catch (error) {
468
499
  console.error(pc.red(error.message));
@@ -472,9 +503,16 @@ localCmd
472
503
  localCmd
473
504
  .command("down")
474
505
  .description("Stop local development stack")
475
- .action(async () => {
506
+ .option("--target <path>", "Compose file path or target name")
507
+ .option("--slot <number>", "Slot number", parseInt)
508
+ .option("--project <name>", "Docker Compose project name")
509
+ .action(async (options) => {
476
510
  try {
477
- await localDown();
511
+ await localDown({
512
+ target: options.target,
513
+ slot: options.slot,
514
+ project: options.project,
515
+ });
478
516
  }
479
517
  catch (error) {
480
518
  console.error(pc.red(error.message));
@@ -484,9 +522,16 @@ localCmd
484
522
  localCmd
485
523
  .command("status")
486
524
  .description("Show local stack status and ports")
487
- .action(async () => {
525
+ .option("--target <path>", "Compose file path or target name")
526
+ .option("--slot <number>", "Slot number", parseInt)
527
+ .option("--project <name>", "Docker Compose project name")
528
+ .action(async (options) => {
488
529
  try {
489
- await localStatus();
530
+ await localStatus({
531
+ target: options.target,
532
+ slot: options.slot,
533
+ project: options.project,
534
+ });
490
535
  }
491
536
  catch (error) {
492
537
  console.error(pc.red(error.message));
@@ -498,9 +543,50 @@ localCmd
498
543
  .description("View local stack logs")
499
544
  .option("-f, --follow", "Follow log output")
500
545
  .option("-s, --service <name>", "Specific service to show logs for")
546
+ .option("--target <path>", "Compose file path or target name")
547
+ .option("--slot <number>", "Slot number", parseInt)
548
+ .option("--project <name>", "Docker Compose project name")
549
+ .action(async (options) => {
550
+ try {
551
+ await localLogs({
552
+ follow: options.follow,
553
+ service: options.service,
554
+ target: options.target,
555
+ slot: options.slot,
556
+ project: options.project,
557
+ });
558
+ }
559
+ catch (error) {
560
+ console.error(pc.red(error.message));
561
+ process.exit(1);
562
+ }
563
+ });
564
+ localCmd
565
+ .command("doctor")
566
+ .description("Run preflight checks (port availability, compose file) without starting")
567
+ .option("--target <path>", "Compose file path or target name")
568
+ .option("--slot <number>", "Slot number", parseInt)
569
+ .option("--project <name>", "Docker Compose project name")
570
+ .action(async (options) => {
571
+ try {
572
+ await localDoctor({
573
+ target: options.target,
574
+ slot: options.slot,
575
+ project: options.project,
576
+ });
577
+ }
578
+ catch (error) {
579
+ console.error(pc.red(error.message));
580
+ process.exit(1);
581
+ }
582
+ });
583
+ localCmd
584
+ .command("smoke")
585
+ .description("Quick smoke test — verify local stack API is reachable")
586
+ .option("--slot <number>", "Slot number", parseInt)
501
587
  .action(async (options) => {
502
588
  try {
503
- await localLogs({ follow: options.follow, service: options.service });
589
+ await localSmoke({ slot: options.slot });
504
590
  }
505
591
  catch (error) {
506
592
  console.error(pc.red(error.message));
@@ -579,5 +665,193 @@ program
579
665
  process.exit(1);
580
666
  }
581
667
  });
668
+ // Issue tracking commands
669
+ const issueCmd = program.command("issue").description("Manage issues (integrated issue tracking)");
670
+ issueCmd
671
+ .command("create")
672
+ .description("Create a new issue")
673
+ .requiredOption("-t, --title <title>", "Issue title")
674
+ .option("-d, --description <desc>", "Issue description")
675
+ .option("--type <type>", "Issue type: bug, feature, task, epic", "task")
676
+ .option("--priority <priority>", "Priority: P0, P1, P2, P3, P4", "P2")
677
+ .option("--project <id>", "Project ID")
678
+ .option("--parent <id>", "Parent issue ID (for sub-tasks)")
679
+ .option("-l, --labels <labels>", "Comma-separated labels")
680
+ .action(async (options) => {
681
+ try {
682
+ await createIssue({
683
+ title: options.title,
684
+ description: options.description,
685
+ type: options.type,
686
+ priority: options.priority,
687
+ project: options.project,
688
+ parent: options.parent,
689
+ labels: options.labels?.split(",").map((l) => l.trim()),
690
+ });
691
+ }
692
+ catch (error) {
693
+ console.error(pc.red(error.message));
694
+ process.exit(1);
695
+ }
696
+ });
697
+ issueCmd
698
+ .command("list")
699
+ .alias("ls")
700
+ .description("List issues")
701
+ .option("-s, --status <status>", "Filter by status: open, in_progress, review, closed")
702
+ .option("--type <type>", "Filter by type: bug, feature, task, epic")
703
+ .option("--priority <priority>", "Filter by priority: P0, P1, P2, P3, P4")
704
+ .option("-a, --assignee <id>", "Filter by assignee (use 'me' for self)")
705
+ .option("--project <id>", "Filter by project")
706
+ .option("-n, --limit <n>", "Number of issues to show", "20")
707
+ .action(async (options) => {
708
+ try {
709
+ await listIssues({
710
+ status: options.status,
711
+ type: options.type,
712
+ priority: options.priority,
713
+ assignee: options.assignee,
714
+ project: options.project,
715
+ limit: parseInt(options.limit, 10),
716
+ });
717
+ }
718
+ catch (error) {
719
+ console.error(pc.red(error.message));
720
+ process.exit(1);
721
+ }
722
+ });
723
+ issueCmd
724
+ .command("show")
725
+ .description("Show issue details")
726
+ .argument("<id>", "Issue ID (e.g., agentmesh-abc)")
727
+ .action(async (id) => {
728
+ try {
729
+ await showIssue(id);
730
+ }
731
+ catch (error) {
732
+ console.error(pc.red(error.message));
733
+ process.exit(1);
734
+ }
735
+ });
736
+ issueCmd
737
+ .command("update")
738
+ .description("Update an issue")
739
+ .argument("<id>", "Issue ID")
740
+ .option("-t, --title <title>", "New title")
741
+ .option("-d, --description <desc>", "New description")
742
+ .option("--type <type>", "New type")
743
+ .option("--priority <priority>", "New priority")
744
+ .option("-s, --status <status>", "New status")
745
+ .option("--project <id>", "Assign to project")
746
+ .option("-a, --assignee <id>", "Assign to agent")
747
+ .option("-l, --labels <labels>", "Comma-separated labels")
748
+ .action(async (id, options) => {
749
+ try {
750
+ await updateIssue(id, {
751
+ title: options.title,
752
+ description: options.description,
753
+ type: options.type,
754
+ priority: options.priority,
755
+ status: options.status,
756
+ project: options.project,
757
+ assignee: options.assignee,
758
+ labels: options.labels?.split(",").map((l) => l.trim()),
759
+ });
760
+ }
761
+ catch (error) {
762
+ console.error(pc.red(error.message));
763
+ process.exit(1);
764
+ }
765
+ });
766
+ issueCmd
767
+ .command("close")
768
+ .description("Close an issue")
769
+ .argument("<id>", "Issue ID")
770
+ .action(async (id) => {
771
+ try {
772
+ await closeIssue(id);
773
+ }
774
+ catch (error) {
775
+ console.error(pc.red(error.message));
776
+ process.exit(1);
777
+ }
778
+ });
779
+ issueCmd
780
+ .command("claim")
781
+ .description("Claim an issue (assign to self and set in_progress)")
782
+ .argument("<id>", "Issue ID")
783
+ .action(async (id) => {
784
+ try {
785
+ await claimIssue(id);
786
+ }
787
+ catch (error) {
788
+ console.error(pc.red(error.message));
789
+ process.exit(1);
790
+ }
791
+ });
792
+ issueCmd
793
+ .command("handoff")
794
+ .description("Hand off an issue to another agent (creates handoff record)")
795
+ .argument("<id>", "Issue ID")
796
+ .requiredOption("--to <agent>", "Target agent ID")
797
+ .option("-r, --reason <reason>", "Reason for handoff")
798
+ .action(async (id, options) => {
799
+ try {
800
+ await handoffIssue(id, { to: options.to, reason: options.reason });
801
+ }
802
+ catch (error) {
803
+ console.error(pc.red(error.message));
804
+ process.exit(1);
805
+ }
806
+ });
807
+ // Inbox command
808
+ program
809
+ .command("inbox")
810
+ .description("Show your assigned issues and pending handoffs")
811
+ .option("-n, --name <name>", "Agent name")
812
+ .option("--type <type>", "Filter by type (handoff|issue)")
813
+ .option("--all", "Include all statuses")
814
+ .option("--json", "Output as JSON")
815
+ .action(async (options) => {
816
+ try {
817
+ await inbox({
818
+ name: options.name,
819
+ type: options.type,
820
+ includeAll: options.all,
821
+ json: options.json,
822
+ });
823
+ }
824
+ catch (error) {
825
+ console.error(pc.red(error.message));
826
+ process.exit(1);
827
+ }
828
+ });
829
+ // Ready command
830
+ program
831
+ .command("ready")
832
+ .description("Show available unassigned work")
833
+ .action(async () => {
834
+ try {
835
+ await ready();
836
+ }
837
+ catch (error) {
838
+ console.error(pc.red(error.message));
839
+ process.exit(1);
840
+ }
841
+ });
842
+ // Sync command
843
+ program
844
+ .command("sync")
845
+ .description("Sync local issue cache with AgentMesh HQ")
846
+ .option("-f, --force", "Force sync even if there are errors")
847
+ .action(async (options) => {
848
+ try {
849
+ await sync({ force: options.force });
850
+ }
851
+ catch (error) {
852
+ console.error(pc.red(error.message));
853
+ process.exit(1);
854
+ }
855
+ });
582
856
  program.parse();
583
857
  //# sourceMappingURL=index.js.map