@memnexus-ai/mx-agent-cli 0.1.174 → 0.1.176

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 (40) hide show
  1. package/dist/__tests__/config-command.test.js +20 -0
  2. package/dist/__tests__/config-command.test.js.map +1 -1
  3. package/dist/__tests__/coordination-brief.test.js +5 -1
  4. package/dist/__tests__/coordination-brief.test.js.map +1 -1
  5. package/dist/__tests__/coordination-command.test.js +2 -0
  6. package/dist/__tests__/coordination-command.test.js.map +1 -1
  7. package/dist/__tests__/coordination-history.test.js +5 -1
  8. package/dist/__tests__/coordination-history.test.js.map +1 -1
  9. package/dist/__tests__/coordination-memory.test.d.ts +14 -0
  10. package/dist/__tests__/coordination-memory.test.d.ts.map +1 -0
  11. package/dist/__tests__/coordination-memory.test.js +261 -0
  12. package/dist/__tests__/coordination-memory.test.js.map +1 -0
  13. package/dist/__tests__/coordination-provision.test.d.ts +12 -0
  14. package/dist/__tests__/coordination-provision.test.d.ts.map +1 -0
  15. package/dist/__tests__/coordination-provision.test.js +77 -0
  16. package/dist/__tests__/coordination-provision.test.js.map +1 -0
  17. package/dist/__tests__/coordination-token.test.d.ts +11 -0
  18. package/dist/__tests__/coordination-token.test.d.ts.map +1 -0
  19. package/dist/__tests__/coordination-token.test.js +166 -0
  20. package/dist/__tests__/coordination-token.test.js.map +1 -0
  21. package/dist/commands/config.d.ts.map +1 -1
  22. package/dist/commands/config.js +12 -0
  23. package/dist/commands/config.js.map +1 -1
  24. package/dist/commands/coordination.d.ts +37 -17
  25. package/dist/commands/coordination.d.ts.map +1 -1
  26. package/dist/commands/coordination.js +145 -16
  27. package/dist/commands/coordination.js.map +1 -1
  28. package/dist/lib/coordination-client.d.ts +21 -0
  29. package/dist/lib/coordination-client.d.ts.map +1 -1
  30. package/dist/lib/coordination-client.js +24 -0
  31. package/dist/lib/coordination-client.js.map +1 -1
  32. package/dist/lib/coordination-memory.d.ts +125 -0
  33. package/dist/lib/coordination-memory.d.ts.map +1 -0
  34. package/dist/lib/coordination-memory.js +318 -0
  35. package/dist/lib/coordination-memory.js.map +1 -0
  36. package/dist/lib/coordination-token.d.ts +75 -0
  37. package/dist/lib/coordination-token.d.ts.map +1 -0
  38. package/dist/lib/coordination-token.js +168 -0
  39. package/dist/lib/coordination-token.js.map +1 -0
  40. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordination-provision.test.js","sourceRoot":"","sources":["../../src/__tests__/coordination-provision.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * coordination-token -- self-provisioning the coordination service token.
3
+ *
4
+ * Verifies the CLI reproduces the coordination-brief hook's isolation properties:
5
+ * marker-authoritative slug (MF-2), roster-gate before any az call (SF-2),
6
+ * slug-bound per-worktree cache (MF-1), born-0600 cache write (SF-3),
7
+ * fail-OPEN on infra errors, fail-CLOSED on a roster mismatch, and no token
8
+ * logging.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=coordination-token.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordination-token.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/coordination-token.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * coordination-token -- self-provisioning the coordination service token.
3
+ *
4
+ * Verifies the CLI reproduces the coordination-brief hook's isolation properties:
5
+ * marker-authoritative slug (MF-2), roster-gate before any az call (SF-2),
6
+ * slug-bound per-worktree cache (MF-1), born-0600 cache write (SF-3),
7
+ * fail-OPEN on infra errors, fail-CLOSED on a roster mismatch, and no token
8
+ * logging.
9
+ */
10
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
11
+ import { mkdtempSync, rmSync, writeFileSync, readFileSync, statSync, existsSync } from 'fs';
12
+ import { join } from 'path';
13
+ import { tmpdir } from 'os';
14
+ // Mock the config store so we can simulate getConfigValue throwing (mkdirSync
15
+ // EACCES on an unwritable HOME) for the SF-A belt-and-suspenders test. Default
16
+ // returns undefined (no configured token) so the other tests reach the marker path.
17
+ vi.mock('../lib/config.js', () => ({ getConfigValue: vi.fn(() => undefined) }));
18
+ import { resolveCoordinationToken, KEYVAULT_NAME } from '../lib/coordination-token.js';
19
+ import { getConfigValue } from '../lib/config.js';
20
+ const mockGetConfigValue = getConfigValue;
21
+ let dir;
22
+ beforeEach(() => {
23
+ dir = mkdtempSync(join(tmpdir(), 'coord-token-'));
24
+ mockGetConfigValue.mockReset();
25
+ mockGetConfigValue.mockReturnValue(undefined);
26
+ });
27
+ afterEach(() => {
28
+ rmSync(dir, { recursive: true, force: true });
29
+ vi.restoreAllMocks();
30
+ });
31
+ /** In-memory readFileText backed by a path→contents map. */
32
+ function reader(files) {
33
+ return (p) => (p in files ? files[p] : undefined);
34
+ }
35
+ describe('resolveCoordinationToken', () => {
36
+ it('uses an already-set env token and never calls Key Vault', () => {
37
+ const fetchSecret = vi.fn();
38
+ const res = resolveCoordinationToken({
39
+ env: { MX_COORD_SERVICE_TOKEN: 'env-tok', CLAUDE_WORKTREE_PATH: dir },
40
+ fetchSecret,
41
+ });
42
+ expect(res.status).toBe('already-configured');
43
+ expect(res.token).toBe('env-tok');
44
+ expect(fetchSecret).not.toHaveBeenCalled();
45
+ });
46
+ it('uses the per-worktree cache when present and never calls Key Vault', () => {
47
+ const fetchSecret = vi.fn();
48
+ const marker = join(dir, '.mx-coordination-team');
49
+ const cache = join(dir, '.mx-coordination-token-eval');
50
+ const res = resolveCoordinationToken({
51
+ env: { CLAUDE_WORKTREE_PATH: dir },
52
+ readFileText: reader({ [marker]: 'eval\n', [cache]: 'cached-eval-tok\n' }),
53
+ fetchSecret,
54
+ });
55
+ expect(res.status).toBe('resolved');
56
+ expect(res.source).toBe('cache');
57
+ expect(res.token).toBe('cached-eval-tok');
58
+ expect(fetchSecret).not.toHaveBeenCalled();
59
+ });
60
+ it('fetches from Key Vault on a cache miss, caches born-0600, and returns it', () => {
61
+ // Real fs so we can assert the on-disk cache mode.
62
+ writeFileSync(join(dir, '.mx-coordination-team'), 'eval\n');
63
+ const fetchSecret = vi.fn((_vault, name) => {
64
+ expect(name).toBe('coordination-token-eval');
65
+ return 'kv-fetched-tok';
66
+ });
67
+ const res = resolveCoordinationToken({ env: { CLAUDE_WORKTREE_PATH: dir }, fetchSecret });
68
+ expect(res.status).toBe('resolved');
69
+ expect(res.source).toBe('keyvault');
70
+ expect(res.token).toBe('kv-fetched-tok');
71
+ expect(fetchSecret).toHaveBeenCalledWith(KEYVAULT_NAME, 'coordination-token-eval');
72
+ const cachePath = join(dir, '.mx-coordination-token-eval');
73
+ expect(existsSync(cachePath)).toBe(true);
74
+ expect(readFileSync(cachePath, 'utf-8')).toBe('kv-fetched-tok');
75
+ // SF-3: born 0600 — no group/other bits.
76
+ expect(statSync(cachePath).mode & 0o777).toBe(0o600);
77
+ });
78
+ it('fails CLOSED on an unknown-slug marker — no Key Vault fetch', () => {
79
+ const fetchSecret = vi.fn();
80
+ const marker = join(dir, '.mx-coordination-team');
81
+ const res = resolveCoordinationToken({
82
+ env: { CLAUDE_WORKTREE_PATH: dir },
83
+ readFileText: reader({ [marker]: 'not-a-real-team\n' }),
84
+ fetchSecret,
85
+ });
86
+ expect(res.status).toBe('not-on-roster');
87
+ expect(res.slug).toBe('not-a-real-team');
88
+ expect(res.token).toBeUndefined();
89
+ expect(fetchSecret).not.toHaveBeenCalled();
90
+ });
91
+ it('MF-1: a stale cross-team cache is never read — marker=marketing ignores eval cache', () => {
92
+ // The worktree was recycled from eval to marketing: eval's cache lingers, but
93
+ // the marketing marker must fetch marketing's token, never reuse eval's.
94
+ const marker = join(dir, '.mx-coordination-team');
95
+ const evalCache = join(dir, '.mx-coordination-token-eval');
96
+ const fetchSecret = vi.fn(() => 'marketing-tok');
97
+ const res = resolveCoordinationToken({
98
+ env: { CLAUDE_WORKTREE_PATH: dir },
99
+ readFileText: reader({ [marker]: 'marketing\n', [evalCache]: 'STALE-EVAL-TOKEN' }),
100
+ fetchSecret,
101
+ });
102
+ expect(res.slug).toBe('marketing');
103
+ expect(res.token).toBe('marketing-tok');
104
+ expect(res.token).not.toBe('STALE-EVAL-TOKEN');
105
+ // It fetched marketing's secret, never touched eval's.
106
+ expect(fetchSecret).toHaveBeenCalledWith(KEYVAULT_NAME, 'coordination-token-marketing');
107
+ });
108
+ it('fails OPEN when Key Vault / az errors — reports unprovisioned, never throws', () => {
109
+ const marker = join(dir, '.mx-coordination-team');
110
+ // Mock az failure: fetchSecret returns undefined (az not logged in / KV down).
111
+ const fetchSecret = vi.fn(() => undefined);
112
+ const res = resolveCoordinationToken({
113
+ env: { CLAUDE_WORKTREE_PATH: dir },
114
+ readFileText: reader({ [marker]: 'eval\n' }),
115
+ fetchSecret,
116
+ });
117
+ expect(res.status).toBe('unprovisioned');
118
+ expect(res.slug).toBe('eval');
119
+ expect(res.token).toBeUndefined();
120
+ expect(res.detail).toMatch(/Key Vault/);
121
+ });
122
+ it('fails OPEN when the marker is missing', () => {
123
+ const res = resolveCoordinationToken({
124
+ env: { CLAUDE_WORKTREE_PATH: dir },
125
+ readFileText: reader({}),
126
+ fetchSecret: vi.fn(),
127
+ });
128
+ expect(res.status).toBe('unprovisioned');
129
+ expect(res.detail).toMatch(/no coordination marker/);
130
+ });
131
+ it('fails OPEN when CLAUDE_WORKTREE_PATH is unset (no marker to read)', () => {
132
+ const res = resolveCoordinationToken({ env: {}, fetchSecret: vi.fn() });
133
+ expect(res.status).toBe('unprovisioned');
134
+ expect(res.detail).toMatch(/CLAUDE_WORKTREE_PATH/);
135
+ });
136
+ it('SF-A: never throws when the config read throws (unwritable HOME) — continues to the marker path', () => {
137
+ mockGetConfigValue.mockImplementation(() => { throw new Error("EACCES: permission denied, mkdir '/home/nobody/.mx-agent'"); });
138
+ const marker = join(dir, '.mx-coordination-team');
139
+ const cache = join(dir, '.mx-coordination-token-eval');
140
+ let res;
141
+ expect(() => {
142
+ res = resolveCoordinationToken({
143
+ env: { CLAUDE_WORKTREE_PATH: dir },
144
+ readFileText: reader({ [marker]: 'eval\n', [cache]: 'cached-eval-tok' }),
145
+ fetchSecret: vi.fn(),
146
+ });
147
+ }).not.toThrow();
148
+ // The config throw was swallowed → resolution proceeded to the cache.
149
+ expect(res?.status).toBe('resolved');
150
+ expect(res?.token).toBe('cached-eval-tok');
151
+ });
152
+ it('never logs the token to the console', () => {
153
+ const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
154
+ const errSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
155
+ const marker = join(dir, '.mx-coordination-team');
156
+ const cache = join(dir, '.mx-coordination-token-eval');
157
+ resolveCoordinationToken({
158
+ env: { CLAUDE_WORKTREE_PATH: dir },
159
+ readFileText: reader({ [marker]: 'eval\n', [cache]: 'secret-token-value' }),
160
+ fetchSecret: vi.fn(() => 'secret-token-value'),
161
+ });
162
+ const all = [...logSpy.mock.calls, ...errSpy.mock.calls].flat().join(' ');
163
+ expect(all).not.toContain('secret-token-value');
164
+ });
165
+ });
166
+ //# sourceMappingURL=coordination-token.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordination-token.test.js","sourceRoot":"","sources":["../../src/__tests__/coordination-token.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuCD,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAgFtD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8CD,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAuFtD"}
@@ -18,6 +18,12 @@ const KNOWN_KEYS = {
18
18
  'coordination-service-url': 'MX Agent Coordination Service base URL (https://...)',
19
19
  'coordination-service-token': 'Per-team bearer token for the MX Agent Coordination Service',
20
20
  'coordination-brief-enabled': 'Run `mx-agent coordination brief` at session start (true to opt in; default off)',
21
+ 'coordination-mode': 'Coordination backend: queue | memory (default memory; `queue` routes escalate/brief to the coordination service)',
22
+ 'coordination-team': 'Sender team for memory-mode coordination when no .mx-coordination-team marker is present',
23
+ };
24
+ /** Config keys constrained to a fixed set of values, validated on `set`. */
25
+ const ENUM_KEYS = {
26
+ 'coordination-mode': ['queue', 'memory'],
21
27
  };
22
28
  /** Keys whose value is a secret and must never be echoed in the clear. */
23
29
  const SECRET_KEYS = new Set(['observability-api-token', 'coordination-service-token']);
@@ -55,6 +61,12 @@ export function runConfig(options) {
55
61
  process.exit(1);
56
62
  }
57
63
  validateKey(key);
64
+ // Validate enum-constrained keys (e.g. coordination-mode).
65
+ const allowed = ENUM_KEYS[key];
66
+ if (allowed && !allowed.includes(value)) {
67
+ console.error(chalk.red(`Error: ${key} must be one of: ${allowed.join(', ')} (got "${value}").`));
68
+ process.exit(1);
69
+ }
58
70
  // Validate HTTPS for webhook URLs
59
71
  if (key === 'slack-webhook') {
60
72
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,37 @@
10
10
  * only a local durable fallback file and flushes it on the next success.
11
11
  */
12
12
  import { type CoordinationClient } from '../lib/coordination-client.js';
13
+ import { type MemoryStore } from '../lib/coordination-memory.js';
14
+ /**
15
+ * Build the HTTP client, self-provisioning the coordination token from Key Vault
16
+ * when none is configured. This ports the coordination-brief hook's KV-fetch into
17
+ * the CLI so a bare `mx-agent coordination brief` (and drain/escalate/history)
18
+ * works standalone with the SAME isolation the security review required (marker
19
+ * authoritative, roster-gated, slug-bound per-worktree 0600 cache, no global-
20
+ * config clobber, no token logging).
21
+ *
22
+ * Returns null — never throws — when a token cannot be provisioned, so the caller
23
+ * degrades cleanly (falls back to the manual channel) instead of crashing:
24
+ * - roster mismatch → fail-CLOSED (no KV fetch), one-line notice.
25
+ * - infra/no-marker → fail-OPEN, one-line notice.
26
+ * When a client IS injected (tests), provisioning is skipped entirely.
27
+ *
28
+ * The resolved token is set in-memory (process env for the request) and is NEVER
29
+ * written to the global ~/.mx-agent config (the MF-2 cross-worktree-clobber
30
+ * defect) and NEVER logged.
31
+ */
32
+ export declare function prepareClient(deps?: {
33
+ client?: CoordinationClient;
34
+ }): CoordinationClient | null;
35
+ /**
36
+ * Injectable dependencies for the coordination commands. `client` stubs the
37
+ * queue service (queue mode); `memoryStore` stubs the named-memory backend
38
+ * (memory mode). Tests inject one or both; production uses the real defaults.
39
+ */
40
+ export interface CoordinationDeps {
41
+ client?: CoordinationClient;
42
+ memoryStore?: MemoryStore;
43
+ }
13
44
  export interface EscalateOptions {
14
45
  to: string;
15
46
  priority: string;
@@ -22,9 +53,7 @@ export interface EscalateOptions {
22
53
  * (exit 0, non-lossy). On success, any previously queued-locally entries are
23
54
  * flushed first.
24
55
  */
25
- export declare function runEscalate(opts: EscalateOptions, deps?: {
26
- client?: CoordinationClient;
27
- }): Promise<void>;
56
+ export declare function runEscalate(opts: EscalateOptions, deps?: CoordinationDeps): Promise<void>;
28
57
  export interface DrainOptions {
29
58
  all?: boolean;
30
59
  limit?: string;
@@ -44,9 +73,7 @@ export interface DrainOptions {
44
73
  * flushed to stdout, the batch is confirmed (MAJOR-2); a mid-render crash leaves
45
74
  * it pending for re-queue. `--no-confirm` leaves the batch unconfirmed.
46
75
  */
47
- export declare function runDrain(opts: DrainOptions, deps?: {
48
- client?: CoordinationClient;
49
- }): Promise<void>;
76
+ export declare function runDrain(opts: DrainOptions, deps?: CoordinationDeps): Promise<void>;
50
77
  export interface BriefOptions {
51
78
  limit?: number;
52
79
  /**
@@ -65,9 +92,7 @@ export interface BriefOptions {
65
92
  * (a mid-render crash leaves it pending → re-queued). Bodies are truncated to
66
93
  * keep the block under the token ceiling for any backlog.
67
94
  */
68
- export declare function runBrief(opts?: BriefOptions, deps?: {
69
- client?: CoordinationClient;
70
- }): Promise<void>;
95
+ export declare function runBrief(opts?: BriefOptions, deps?: CoordinationDeps): Promise<void>;
71
96
  export interface WatchOptions {
72
97
  intervalMs?: number;
73
98
  limit?: number;
@@ -98,14 +123,11 @@ export declare function redactSecrets(s: string): string;
98
123
  * hint. Full harness onInject + the Redis blocking-read server push stay OUT of
99
124
  * scope (see README).
100
125
  */
101
- export declare function runWatch(opts?: WatchOptions, deps?: {
102
- client?: CoordinationClient;
126
+ export declare function runWatch(opts?: WatchOptions, deps?: CoordinationDeps & {
103
127
  sleep?: (ms: number) => Promise<void>;
104
128
  }): Promise<void>;
105
129
  /** FR-7 ack. */
106
- export declare function runAck(messageId: string, deps?: {
107
- client?: CoordinationClient;
108
- }): Promise<void>;
130
+ export declare function runAck(messageId: string, deps?: CoordinationDeps): Promise<void>;
109
131
  export interface HistoryOptions {
110
132
  /** Page size (service default 50, cap 200). */
111
133
  limit?: string;
@@ -120,7 +142,5 @@ export interface HistoryOptions {
120
142
  * payload in a body stays inside the fence and is never emitted raw. `--all`
121
143
  * follows the `nextBefore` cursor to page the full history (most-recent-first).
122
144
  */
123
- export declare function runHistory(opts?: HistoryOptions, deps?: {
124
- client?: CoordinationClient;
125
- }): Promise<void>;
145
+ export declare function runHistory(opts?: HistoryOptions, deps?: CoordinationDeps): Promise<void>;
126
146
  //# sourceMappingURL=coordination.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"coordination.d.ts","sourceRoot":"","sources":["../../src/commands/coordination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAKL,KAAK,kBAAkB,EAExB,MAAM,+BAA+B,CAAC;AAwEvC,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC9G;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBxG;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE,YAAiB,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C7G;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,qBAAa,cAAe,SAAQ,KAAK;;CAKxC;AAQD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,GAAE,YAAiB,EACvB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAC5E,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED,gBAAgB;AAChB,wBAAsB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrG;AAED,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAKD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAE,cAAmB,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBjH"}
1
+ {"version":3,"file":"coordination.d.ts","sourceRoot":"","sources":["../../src/commands/coordination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAML,KAAK,kBAAkB,EAExB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAiCvC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,kBAAkB,GAAG,IAAI,CAqC/F;AAkCD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AASD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAkDD;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC/F;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BzF;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE,YAAiB,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+C9F;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,qBAAa,cAAe,SAAQ,KAAK;;CAKxC;AAQD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,GAAE,YAAiB,EACvB,IAAI,CAAC,EAAE,gBAAgB,GAAG;IAAE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAClE,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,gBAAgB;AAChB,wBAAsB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAStF;AAED,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAKD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAE,cAAmB,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBlG"}
@@ -9,9 +9,11 @@
9
9
  * `escalate` degrades safely when the service is unreachable (FR-8): it writes
10
10
  * only a local durable fallback file and flushes it on the next success.
11
11
  */
12
- import { HttpCoordinationClient, resolveClientConfig, ServiceUnreachableError, ServiceHttpError, } from '../lib/coordination-client.js';
12
+ import { HttpCoordinationClient, resolveClientConfig, resolveCoordinationMode, ServiceUnreachableError, ServiceHttpError, } from '../lib/coordination-client.js';
13
+ import { resolveCoordinationToken } from '../lib/coordination-token.js';
13
14
  import { appendFallbackEntry, flushFallback } from '../lib/coordination-fallback.js';
14
15
  import { renderMessages } from '../lib/coordination-render.js';
16
+ import { escalateToOutbox, readEscalationsForTeam, renderEscalationBlocks, resolveMemoryTeam, resolveProductSlug, } from '../lib/coordination-memory.js';
15
17
  const VALID_PRIORITIES = new Set(['p0', 'p1', 'p2', 'p3']);
16
18
  /** Truncate each body to this many chars in the brief (token-ceiling control). */
17
19
  const BRIEF_BODY_MAX_CHARS = 500;
@@ -38,9 +40,60 @@ function flushStdout() {
38
40
  process.stdout.write('', () => resolve());
39
41
  });
40
42
  }
41
- /** Build the default HTTP client from config/env. Overridable in tests. */
42
- function defaultClient() {
43
- return new HttpCoordinationClient(resolveClientConfig());
43
+ /**
44
+ * Build the HTTP client, self-provisioning the coordination token from Key Vault
45
+ * when none is configured. This ports the coordination-brief hook's KV-fetch into
46
+ * the CLI so a bare `mx-agent coordination brief` (and drain/escalate/history)
47
+ * works standalone with the SAME isolation the security review required (marker
48
+ * authoritative, roster-gated, slug-bound per-worktree 0600 cache, no global-
49
+ * config clobber, no token logging).
50
+ *
51
+ * Returns null — never throws — when a token cannot be provisioned, so the caller
52
+ * degrades cleanly (falls back to the manual channel) instead of crashing:
53
+ * - roster mismatch → fail-CLOSED (no KV fetch), one-line notice.
54
+ * - infra/no-marker → fail-OPEN, one-line notice.
55
+ * When a client IS injected (tests), provisioning is skipped entirely.
56
+ *
57
+ * The resolved token is set in-memory (process env for the request) and is NEVER
58
+ * written to the global ~/.mx-agent config (the MF-2 cross-worktree-clobber
59
+ * defect) and NEVER logged.
60
+ */
61
+ export function prepareClient(deps) {
62
+ if (deps?.client)
63
+ return deps.client;
64
+ // SF-A never-crash contract: resolveCoordinationToken is documented never-throws,
65
+ // but its config read can still touch the filesystem (mkdirSync on an unwritable/
66
+ // read-only HOME → EACCES/EROFS). Keep the WHOLE resolve+build inside the
67
+ // try/catch so ANY throw degrades to the null fall-back path — a coordination
68
+ // hiccup must never crash `mx-agent coordination brief` (breaks session start).
69
+ let res = { status: 'unprovisioned', detail: 'token resolution failed' };
70
+ try {
71
+ res = resolveCoordinationToken();
72
+ if (res.status === 'resolved' && res.token) {
73
+ // In-memory only: resolveClientConfig reads MX_COORD_SERVICE_TOKEN in
74
+ // preference to the global config, so we never touch the shared config file.
75
+ process.env.MX_COORD_SERVICE_TOKEN = res.token;
76
+ // SF-B: arm the SF-1 verify-before-confirm interlock on the bare
77
+ // self-provisioned path, matching the hook (which set MX_COORD_EXPECT_TEAM).
78
+ // `??=` so an explicit hook-set value is never overwritten.
79
+ if (res.slug)
80
+ process.env.MX_COORD_EXPECT_TEAM ??= res.slug;
81
+ }
82
+ return new HttpCoordinationClient(resolveClientConfig());
83
+ }
84
+ catch (err) {
85
+ // No usable token/URL (or a resolve-time throw). Report a non-secret, one-line
86
+ // fall-back notice and return null; the caller returns cleanly so the agent
87
+ // uses the old channel.
88
+ if (res.status === 'not-on-roster') {
89
+ process.stderr.write(`coordination: team "${res.slug}" is not on the coordination roster — falling back to the manual channel\n`);
90
+ }
91
+ else {
92
+ const why = res.detail ?? (err instanceof Error ? err.message : String(err));
93
+ process.stderr.write(`coordination: could not provision a service token (${why}) — falling back to the manual channel\n`);
94
+ }
95
+ return null;
96
+ }
44
97
  }
45
98
  /**
46
99
  * Opportunistically flush any queued-locally entries. Surfaces a flush FAILURE
@@ -74,6 +127,52 @@ function writeFallbackOrFail(entry) {
74
127
  throw err;
75
128
  }
76
129
  }
130
+ /** One-line note printed when a queue-only subcommand runs in memory mode. */
131
+ function memoryModeQueueOnlyNote(subcommand) {
132
+ console.log(`coordination-mode=memory: ${subcommand} is queue-only; use \`mx-agent coordination brief\` to read the shared escalations doc`);
133
+ }
134
+ /**
135
+ * memory-mode escalate: append the entry to the sender's outbox memory
136
+ * `<slug>-escalations-<from-team>-outbox` via fetch-edit-verify. No token, no
137
+ * queue service. A failed byte-verify is a hard error (exit 1) so a clobbered
138
+ * or dropped write is never silently reported as success.
139
+ */
140
+ async function runEscalateMemory(opts, deps) {
141
+ const team = resolveMemoryTeam(opts.team);
142
+ const slug = resolveProductSlug();
143
+ let res;
144
+ try {
145
+ res = escalateToOutbox({ fromTeam: team, to: opts.to, priority: opts.priority, body: opts.body, productSlug: slug }, deps?.memoryStore);
146
+ }
147
+ catch (err) {
148
+ // A MemNexus write failure is surfaced (not swallowed) — the message is not
149
+ // queued, so the operator must see it. Exit non-zero.
150
+ console.error(`Error: memory-mode escalate failed to write the outbox: ${err instanceof Error ? err.message : String(err)}`);
151
+ process.exit(1);
152
+ return;
153
+ }
154
+ if (!res.verified) {
155
+ console.error(`Error: memory-mode escalate could not verify the outbox write (${res.name}) — the entry may not have persisted. Not marking as sent.`);
156
+ process.exit(1);
157
+ return;
158
+ }
159
+ console.log(`escalated to ${res.name} (memory mode) -> ${opts.to} [${opts.priority}]${res.created ? ' (outbox created)' : ''}`);
160
+ }
161
+ /**
162
+ * memory-mode brief: read the shared escalations doc and render entries
163
+ * addressed to this team inside the provenance fence. Read-only — there is no
164
+ * drain/confirm in memory mode.
165
+ */
166
+ async function runBriefMemory(opts, deps) {
167
+ const team = opts.expectedTeam ?? resolveMemoryTeam();
168
+ const slug = resolveProductSlug();
169
+ const { present, entries } = readEscalationsForTeam(team, slug, deps?.memoryStore);
170
+ if (!present || entries.length === 0) {
171
+ console.log('no cross-team coordination pending');
172
+ return;
173
+ }
174
+ console.log(renderEscalationBlocks(entries));
175
+ }
77
176
  /**
78
177
  * FR-7 enqueue + FR-8 degraded fallback. On a transport failure the message is
79
178
  * written to the local durable fallback file and reported as queued-locally
@@ -85,16 +184,17 @@ export async function runEscalate(opts, deps) {
85
184
  console.error(`Error: --priority must be one of p0, p1, p2, p3 (got "${opts.priority}").`);
86
185
  process.exit(1);
87
186
  }
187
+ // Backend routing (PO one-interface design). memory mode requires NO token.
188
+ if (resolveCoordinationMode() === 'memory') {
189
+ return runEscalateMemory(opts, deps);
190
+ }
88
191
  const team = resolveTeam(opts.team);
89
192
  const entry = { team, to: opts.to, priority: opts.priority, body: opts.body, from: team };
90
- let client;
91
- try {
92
- client = deps?.client ?? defaultClient();
93
- }
94
- catch (err) {
95
- // No config at all — still degrade to the local fallback so nothing is lost.
193
+ const client = prepareClient(deps);
194
+ if (!client) {
195
+ // No token/URL could be provisioned (prepareClient already printed the reason).
196
+ // Degrade to the local fallback so the message is never lost.
96
197
  writeFallbackOrFail(entry);
97
- console.error(err instanceof Error ? err.message : String(err));
98
198
  console.log('queued locally, will flush on reconnect');
99
199
  return;
100
200
  }
@@ -123,7 +223,13 @@ export async function runEscalate(opts, deps) {
123
223
  * it pending for re-queue. `--no-confirm` leaves the batch unconfirmed.
124
224
  */
125
225
  export async function runDrain(opts, deps) {
126
- const client = deps?.client ?? defaultClient();
226
+ if (resolveCoordinationMode() === 'memory') {
227
+ memoryModeQueueOnlyNote('drain');
228
+ return; // exit 0 — no crash
229
+ }
230
+ const client = prepareClient(deps);
231
+ if (!client)
232
+ return; // could not provision — fall back (prepareClient printed why)
127
233
  // Flush any queued-locally entries now that the service is reachable.
128
234
  await opportunisticFlush(client);
129
235
  const limit = opts.all ? undefined : opts.limit ? parseInt(opts.limit, 10) : undefined;
@@ -152,7 +258,12 @@ export async function runDrain(opts, deps) {
152
258
  * keep the block under the token ceiling for any backlog.
153
259
  */
154
260
  export async function runBrief(opts = {}, deps) {
155
- const client = deps?.client ?? defaultClient();
261
+ if (resolveCoordinationMode() === 'memory') {
262
+ return runBriefMemory(opts, deps);
263
+ }
264
+ const client = prepareClient(deps);
265
+ if (!client)
266
+ return; // could not provision — fall back (prepareClient printed why)
156
267
  await opportunisticFlush(client);
157
268
  const limit = opts.limit ?? envInt('MX_COORD_BRIEF_LIMIT', 10);
158
269
  const res = await client.drain({ limit });
@@ -226,7 +337,13 @@ export function redactSecrets(s) {
226
337
  * scope (see README).
227
338
  */
228
339
  export async function runWatch(opts = {}, deps) {
229
- const client = deps?.client ?? defaultClient();
340
+ if (resolveCoordinationMode() === 'memory') {
341
+ memoryModeQueueOnlyNote('watch');
342
+ return; // exit 0 — no crash
343
+ }
344
+ const client = prepareClient(deps);
345
+ if (!client)
346
+ return; // could not provision — fall back (prepareClient printed why)
230
347
  const intervalMs = opts.intervalMs ?? envInt('MX_COORD_PRIORITY_POLL_MS', 15_000);
231
348
  const limit = opts.limit ?? envInt('MX_COORD_BRIEF_LIMIT', 10);
232
349
  const sleep = deps?.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
@@ -266,7 +383,13 @@ export async function runWatch(opts = {}, deps) {
266
383
  }
267
384
  /** FR-7 ack. */
268
385
  export async function runAck(messageId, deps) {
269
- const client = deps?.client ?? defaultClient();
386
+ if (resolveCoordinationMode() === 'memory') {
387
+ memoryModeQueueOnlyNote('ack');
388
+ return; // exit 0 — no crash
389
+ }
390
+ const client = prepareClient(deps);
391
+ if (!client)
392
+ return; // could not provision — fall back (prepareClient printed why)
270
393
  await client.ack(messageId);
271
394
  console.log(`acked: ${messageId}`);
272
395
  }
@@ -281,7 +404,13 @@ const HISTORY_MAX_PAGES = 500;
281
404
  * follows the `nextBefore` cursor to page the full history (most-recent-first).
282
405
  */
283
406
  export async function runHistory(opts = {}, deps) {
284
- const client = deps?.client ?? defaultClient();
407
+ if (resolveCoordinationMode() === 'memory') {
408
+ memoryModeQueueOnlyNote('history');
409
+ return; // exit 0 — no crash
410
+ }
411
+ const client = prepareClient(deps);
412
+ if (!client)
413
+ return; // could not provision — fall back (prepareClient printed why)
285
414
  const limit = opts.limit ? parseInt(opts.limit, 10) : undefined;
286
415
  const collected = [];
287
416
  let before;