@lumenflow/cli 5.3.1 → 5.4.0

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 (55) hide show
  1. package/README.md +20 -18
  2. package/dist/agent-session.js +21 -0
  3. package/dist/agent-session.js.map +1 -1
  4. package/dist/commands/integrate.js +25 -1
  5. package/dist/commands/integrate.js.map +1 -1
  6. package/dist/gates-runners.js +1 -1
  7. package/dist/gates-runners.js.map +1 -1
  8. package/dist/hooks/enforcement-generator.js +14 -8
  9. package/dist/hooks/enforcement-generator.js.map +1 -1
  10. package/dist/hooks/enforcement-sync.js +2 -1
  11. package/dist/hooks/enforcement-sync.js.map +1 -1
  12. package/dist/hooks/generators/index.js +1 -0
  13. package/dist/hooks/generators/index.js.map +1 -1
  14. package/dist/hooks/generators/signal-received.js +4 -0
  15. package/dist/hooks/generators/signal-received.js.map +1 -0
  16. package/dist/mem-converged.js +101 -0
  17. package/dist/mem-converged.js.map +1 -0
  18. package/dist/mem-inbox.js +85 -22
  19. package/dist/mem-inbox.js.map +1 -1
  20. package/dist/mem-roster.js +11 -1
  21. package/dist/mem-roster.js.map +1 -1
  22. package/dist/mem-signal.js +162 -16
  23. package/dist/mem-signal.js.map +1 -1
  24. package/dist/mem-watch.js +207 -0
  25. package/dist/mem-watch.js.map +1 -0
  26. package/dist/public-manifest.js +14 -0
  27. package/dist/public-manifest.js.map +1 -1
  28. package/dist/session-cross-link.js +14 -2
  29. package/dist/session-cross-link.js.map +1 -1
  30. package/dist/sidecar-manager.js +25 -0
  31. package/dist/sidecar-manager.js.map +1 -1
  32. package/dist/signal-hook.js +351 -0
  33. package/dist/signal-hook.js.map +1 -0
  34. package/dist/wu-prep.js +106 -4
  35. package/dist/wu-prep.js.map +1 -1
  36. package/dist/wu-spawn-prompt-builders.js.map +1 -1
  37. package/dist/wu-spawn-strategy-resolver.js +46 -4
  38. package/dist/wu-spawn-strategy-resolver.js.map +1 -1
  39. package/package.json +13 -11
  40. package/packs/agent-runtime/auto-session-integration.ts +14 -0
  41. package/packs/agent-runtime/package.json +1 -1
  42. package/packs/agent-runtime/session-schema.ts +44 -0
  43. package/packs/sidekick/package.json +1 -1
  44. package/packs/software-delivery/manifest.ts +3 -0
  45. package/packs/software-delivery/manifest.yaml +7 -0
  46. package/packs/software-delivery/package.json +1 -1
  47. package/packs/software-delivery/src/methodology/incremental-test.ts +48 -16
  48. package/packs/software-delivery/src/policy/gates-coverage.ts +10 -0
  49. package/packs/software-delivery/src/policy/resolve-policy.ts +83 -0
  50. package/packs/software-delivery/tool-impl/memory-tools.ts +56 -1
  51. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +1 -0
  52. package/templates/core/AGENTS.md.template +19 -1
  53. package/templates/core/LUMENFLOW.md.template +17 -0
  54. package/templates/core/ai/onboarding/agent-safety-card.md.template +16 -0
  55. package/templates/core/ai/onboarding/vendor-support.md.template +9 -9
@@ -66,10 +66,69 @@ export const ArchitectureMethodologySchema = z.enum(['hexagonal', 'layered', 'no
66
66
  */
67
67
  export const CoverageModeSchema = z.enum(['block', 'warn', 'off']);
68
68
 
69
+ /**
70
+ * WU-2905: Default test-file glob patterns for the tdd_diff_evidence gate.
71
+ *
72
+ * These globs identify files that count as "test evidence" in a branch diff
73
+ * for the default TS/JS toolchain. Mirrors the regex set in
74
+ * `@lumenflow/core/file-classifiers.ts:TEST_FILE_PATTERNS` (the legacy regex
75
+ * form historically used by the gate consumer in wu:prep). When a workspace
76
+ * overrides `tdd_diff_evidence.test_file_patterns`, the gate uses the
77
+ * override exclusively (no merge) so non-TS/JS toolchains (.NET, Python,
78
+ * Go, ...) get a clean opt-in without inheriting TS/JS bias.
79
+ */
80
+ export const DEFAULT_TDD_DIFF_TEST_FILE_PATTERNS: readonly string[] = Object.freeze([
81
+ '**/*.test.ts',
82
+ '**/*.test.tsx',
83
+ '**/*.test.js',
84
+ '**/*.test.jsx',
85
+ '**/*.test.mjs',
86
+ '**/*.spec.ts',
87
+ '**/*.spec.tsx',
88
+ '**/*.spec.js',
89
+ '**/*.spec.jsx',
90
+ '**/*.spec.mjs',
91
+ '**/__tests__/**',
92
+ '**/*.test-utils.*',
93
+ '**/*.mock.*',
94
+ ]);
95
+
96
+ /**
97
+ * WU-2905: Default code file extensions for the tdd_diff_evidence gate.
98
+ *
99
+ * Determines which changed files count as production code that requires
100
+ * accompanying test evidence. Mirrors the historic constant in
101
+ * `methodology/incremental-test.ts:CODE_FILE_EXTENSIONS`.
102
+ */
103
+ export const DEFAULT_TDD_DIFF_CODE_FILE_EXTENSIONS: readonly string[] = Object.freeze([
104
+ '.ts',
105
+ '.tsx',
106
+ '.js',
107
+ '.jsx',
108
+ '.cjs',
109
+ '.mts',
110
+ '.cts',
111
+ ]);
112
+
69
113
  export const TddDiffEvidenceConfigSchema = z.object({
70
114
  mode: CoverageModeSchema.optional(),
71
115
  applies_to_types: z.array(z.enum(WU_TYPE_VALUES)).min(1).optional(),
72
116
  exempt_paths: z.array(z.string().min(1)).optional(),
117
+ /**
118
+ * WU-2905: Optional glob patterns identifying test files for the
119
+ * tdd_diff_evidence gate. When omitted, defaults to TS/JS patterns
120
+ * (DEFAULT_TDD_DIFF_TEST_FILE_PATTERNS). When set, REPLACES the defaults so
121
+ * non-TS/JS consumers can supply only their language's test patterns
122
+ * (e.g. ['**\/*Tests.cs', '**\/Test*.cs'] for C# xUnit/NUnit/MSTest).
123
+ */
124
+ test_file_patterns: z.array(z.string().min(1)).min(1).optional(),
125
+ /**
126
+ * WU-2905: Optional file extensions identifying production code files for
127
+ * the tdd_diff_evidence gate. When omitted, defaults to TS/JS extensions
128
+ * (DEFAULT_TDD_DIFF_CODE_FILE_EXTENSIONS). When set, REPLACES the defaults
129
+ * (e.g. ['.cs'] for C#, ['.py'] for Python, ['.go'] for Go).
130
+ */
131
+ code_file_extensions: z.array(z.string().min(1)).min(1).optional(),
73
132
  });
74
133
 
75
134
  export type TddDiffEvidenceConfig = z.infer<typeof TddDiffEvidenceConfigSchema>;
@@ -275,6 +334,18 @@ export interface TddDiffEvidencePolicy {
275
334
  mode: CoverageMode;
276
335
  applies_to_types: WUType[];
277
336
  exempt_paths: string[];
337
+ /**
338
+ * WU-2905: Resolved glob patterns identifying test files. Always
339
+ * populated — falls back to DEFAULT_TDD_DIFF_TEST_FILE_PATTERNS when the
340
+ * workspace does not override.
341
+ */
342
+ test_file_patterns: string[];
343
+ /**
344
+ * WU-2905: Resolved file extensions identifying production code files.
345
+ * Always populated — falls back to DEFAULT_TDD_DIFF_CODE_FILE_EXTENSIONS
346
+ * when the workspace does not override.
347
+ */
348
+ code_file_extensions: string[];
278
349
  }
279
350
 
280
351
  /**
@@ -342,6 +413,14 @@ function cloneExemptPaths(value: readonly string[] | undefined): string[] {
342
413
  return [...(value ?? DEFAULT_TDD_DIFF_EXEMPT_PATHS)];
343
414
  }
344
415
 
416
+ function cloneTestFilePatterns(value: readonly string[] | undefined): string[] {
417
+ return [...(value ?? DEFAULT_TDD_DIFF_TEST_FILE_PATTERNS)];
418
+ }
419
+
420
+ function cloneCodeFileExtensions(value: readonly string[] | undefined): string[] {
421
+ return [...(value ?? DEFAULT_TDD_DIFF_CODE_FILE_EXTENSIONS)];
422
+ }
423
+
345
424
  function resolveTddDiffEvidencePolicy(
346
425
  testing: TestingMethodology,
347
426
  config: TddDiffEvidenceConfig | undefined,
@@ -350,6 +429,8 @@ function resolveTddDiffEvidencePolicy(
350
429
  mode: config?.mode ?? resolveDefaultTddDiffEvidenceMode(testing),
351
430
  applies_to_types: cloneWuTypes(config?.applies_to_types),
352
431
  exempt_paths: cloneExemptPaths(config?.exempt_paths),
432
+ test_file_patterns: cloneTestFilePatterns(config?.test_file_patterns),
433
+ code_file_extensions: cloneCodeFileExtensions(config?.code_file_extensions),
353
434
  };
354
435
  }
355
436
 
@@ -506,6 +587,8 @@ export function getDefaultPolicy(): ResolvedPolicy {
506
587
  mode: COVERAGE_MODE.BLOCK,
507
588
  applies_to_types: [...DEFAULT_TDD_DIFF_APPLIES_TO_TYPES],
508
589
  exempt_paths: [...DEFAULT_TDD_DIFF_EXEMPT_PATHS],
590
+ test_file_patterns: [...DEFAULT_TDD_DIFF_TEST_FILE_PATTERNS],
591
+ code_file_extensions: [...DEFAULT_TDD_DIFF_CODE_FILE_EXTENSIONS],
509
592
  },
510
593
  tdd_ordering: {
511
594
  mode: COVERAGE_MODE.BLOCK,
@@ -16,6 +16,7 @@ const MEMORY_TOOLS = {
16
16
  MEM_EXPORT: 'mem:export',
17
17
  MEM_INBOX: 'mem:inbox',
18
18
  MEM_SIGNAL: 'mem:signal',
19
+ MEM_CONVERGED: 'mem:converged',
19
20
  MEM_SUMMARIZE: 'mem:summarize',
20
21
  MEM_TRIAGE: 'mem:triage',
21
22
  MEM_RECOVER: 'mem:recover',
@@ -35,6 +36,7 @@ const MEMORY_TOOL_ERROR_CODES: Record<MemoryToolName, string> = {
35
36
  'mem:export': 'MEM_EXPORT_ERROR',
36
37
  'mem:inbox': 'MEM_INBOX_ERROR',
37
38
  'mem:signal': 'MEM_SIGNAL_ERROR',
39
+ 'mem:converged': 'MEM_CONVERGED_ERROR',
38
40
  'mem:summarize': 'MEM_SUMMARIZE_ERROR',
39
41
  'mem:triage': 'MEM_TRIAGE_ERROR',
40
42
  'mem:recover': 'MEM_RECOVER_ERROR',
@@ -55,6 +57,7 @@ const MEMORY_TOOL_COMMANDS: Record<
55
57
  'mem:export': RUNTIME_CLI_COMMANDS.MEM_EXPORT,
56
58
  'mem:inbox': RUNTIME_CLI_COMMANDS.MEM_INBOX,
57
59
  'mem:signal': RUNTIME_CLI_COMMANDS.MEM_SIGNAL,
60
+ 'mem:converged': RUNTIME_CLI_COMMANDS.MEM_CONVERGED,
58
61
  'mem:summarize': RUNTIME_CLI_COMMANDS.MEM_SUMMARIZE,
59
62
  'mem:triage': RUNTIME_CLI_COMMANDS.MEM_TRIAGE,
60
63
  'mem:recover': RUNTIME_CLI_COMMANDS.MEM_RECOVER,
@@ -338,6 +341,18 @@ export async function memInboxTool(input: unknown): Promise<ToolOutput> {
338
341
  if (lane) {
339
342
  args.push('--lane', lane);
340
343
  }
344
+ const reader = toStringValue(parsed.for);
345
+ if (reader) {
346
+ args.push('--for', reader);
347
+ }
348
+ const thread = toStringValue(parsed.thread);
349
+ if (thread) {
350
+ args.push('--thread', thread);
351
+ }
352
+ const intent = toStringValue(parsed.intent);
353
+ if (intent) {
354
+ args.push('--intent', intent);
355
+ }
341
356
 
342
357
  return executeMemoryTool(MEMORY_TOOLS.MEM_INBOX, args);
343
358
  }
@@ -354,7 +369,47 @@ export async function memSignalTool(input: unknown): Promise<ToolOutput> {
354
369
  return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.WU_REQUIRED);
355
370
  }
356
371
 
357
- return executeMemoryTool(MEMORY_TOOLS.MEM_SIGNAL, [message, '--wu', wu]);
372
+ const args = [message, '--wu', wu];
373
+ const to = toStringValue(parsed.to);
374
+ if (to) {
375
+ args.push('--to', to);
376
+ }
377
+ const thread = toStringValue(parsed.thread);
378
+ if (thread) {
379
+ args.push('--thread', thread);
380
+ }
381
+ const replyTo = toStringValue(parsed.reply_to);
382
+ if (replyTo) {
383
+ args.push('--reply-to', replyTo);
384
+ }
385
+ const intent = toStringValue(parsed.intent);
386
+ if (intent) {
387
+ args.push('--intent', intent);
388
+ }
389
+ const interrupt = toStringValue(parsed.interrupt);
390
+ if (interrupt) {
391
+ args.push('--interrupt', interrupt);
392
+ }
393
+ if (parsed.requires_ack === true) {
394
+ args.push('--requires-ack');
395
+ }
396
+
397
+ return executeMemoryTool(MEMORY_TOOLS.MEM_SIGNAL, args);
398
+ }
399
+
400
+ export async function memConvergedTool(input: unknown): Promise<ToolOutput> {
401
+ const parsed = toRecord(input);
402
+ const thread = toStringValue(parsed.thread);
403
+ if (!thread) {
404
+ return createMissingParameterOutput('thread is required');
405
+ }
406
+
407
+ const args = ['--thread', thread];
408
+ if (parsed.quiet === true) {
409
+ args.push('--quiet');
410
+ }
411
+
412
+ return executeMemoryTool(MEMORY_TOOLS.MEM_CONVERGED, args);
358
413
  }
359
414
 
360
415
  export async function memSummarizeTool(input: unknown): Promise<ToolOutput> {
@@ -47,6 +47,7 @@ export const RUNTIME_CLI_COMMANDS = {
47
47
  MEM_DELETE: 'mem-delete',
48
48
  MEM_EXPORT: 'mem-export',
49
49
  MEM_INBOX: 'mem-inbox',
50
+ MEM_CONVERGED: 'mem-converged',
50
51
  MEM_INIT: 'mem-init',
51
52
  MEM_READY: 'mem-ready',
52
53
  MEM_RECOVER: 'mem-recover',
@@ -70,7 +70,7 @@ cd <project-root> && pnpm wu:done --id WU-XXXX
70
70
  Step 2 above is not optional:
71
71
 
72
72
  - `wu:brief` records checkpoint evidence; `wu:done` **blocks** without it for feature/bug WUs.
73
- - `wu:brief` also auto-loads shared memory and coordination signals into the generated prompt (WU-1240, WU-2607) — read the `## Memory Context` section in the brief output before coding. Manual `mem:context`/`mem:inbox` calls are still available as ad-hoc lookups mid-WU.
73
+ - `wu:brief` also auto-loads shared memory and an Inbox Snapshot into the generated prompt (WU-1240, WU-2607) — read the `## Memory Context` section in the brief output before coding. Manual `mem:context`/`mem:inbox` calls are still available as ad-hoc lookups mid-WU.
74
74
  - Load relevant skills (`design-first`, `tdd-workflow`, `frontend-design`, `worktree-discipline`, `lumenflow-gates`) via your vendor's skill primitive. Claude Code, Codex, Cursor, and Windsurf all support `SKILL.md`-based skills (with minor invocation differences); Aider uses `CONVENTIONS.md`; Cline uses `.clinerules`. See [LUMENFLOW.md "Skills & Agents"](LUMENFLOW.md#skills--agents) for the invocation table, and your per-vendor rules file for specifics.
75
75
 
76
76
  ### During the WU
@@ -83,6 +83,16 @@ pnpm mem:signal '<short status>' --wu WU-XXXX
83
83
  pnpm mem:checkpoint --wu WU-XXXX --note '<progress>' --next-steps '<what is next>'
84
84
  ```
85
85
 
86
+ ### Inbox Signals Are Decision Points
87
+
88
+ At `wu:brief`, after every `mem:checkpoint`, and before `wu:prep`, inspect unread coordination
89
+ signals for your WU/session. A signal is not noise: read it, decide whether it changes or blocks the
90
+ WU, and reply, acknowledge, or dismiss it before continuing.
91
+
92
+ This convention applies to Claude Code, Codex, Cursor, Gemini CLI, and Windsurf briefs. Aider and
93
+ Cline do not use `wu:brief` client variants, but they must follow the same polling rule through this
94
+ onboarding guidance and their generated rules surfaces.
95
+
86
96
  **Classification rule:** if the fact would help _another_ agent vendor working this repo, it belongs in shared memory (`mem:create`), not your vendor's personal memory folder. Examples of shared: bug discoveries, architecture decisions, CI/gates gotchas, initiative direction, cross-WU scope flags. Examples of vendor-personal: behavioural feedback, user preferences, tool-invocation mechanics.
87
97
 
88
98
  **Shell-quoting footgun:** always **single-quote** the `--title` value. Bash expands `$var`, `$0`, backticks, and `!hist` inside double-quoted strings, silently corrupting prose containing prices (`$49`), positional refs, or exclamation marks. See [Memory section in LUMENFLOW.md](LUMENFLOW.md#memory-shared-vs-vendor-personal) for the full mem:\* contract.
@@ -204,6 +214,14 @@ LumenFlow enforces safety at the repository level via git wrappers and hooks. Fo
204
214
 
205
215
  This file provides universal guidance for all AI agents. LumenFlow skills live in `.lumenflow/skills/` as `SKILL.md` files and are projected to each vendor via `pnpm lumenflow:integrate --client <x>`.
206
216
 
217
+ Agent plugins are a discovery and invocation on-ramp, not a replacement for repo-level LumenFlow
218
+ integration. If a plugin is installed alongside standalone projections, use the surface-specific
219
+ name: standalone skills keep local names such as `design-first`, Claude plugin skills use names such
220
+ as `/lumenflow:design-first`, and Codex plugin use should select the installed `lumenflow` plugin or
221
+ bundled skill through Codex's `@` plugin selection surface. Plugin installation must not delete
222
+ `.claude/skills/` or `.agents/skills/`, and governed repo enforcement still requires
223
+ `npx lumenflow init`, `pnpm lumenflow:integrate`, or `pnpm lumenflow:integrate --sync`.
224
+
207
225
  | Vendor | Skill / rules surface | Invocation |
208
226
  | ------------ | --------------------------------------------------- | ---------------------------------------------------------------------- |
209
227
  | Claude Code | `.claude/skills/` + `.claude/CLAUDE.md` | `Skill` tool call, or `/skill <name>` in interactive CLI |
@@ -727,6 +727,15 @@ If you're an AI agent, read the onboarding docs:
727
727
 
728
728
  Skills are reusable workflow/knowledge bundles that agents load on demand. The `SKILL.md` format pioneered by Claude Code has converged into a de-facto standard adopted by OpenAI Codex (Dec 2025), Cursor (v2.4), and Windsurf Cascade (Jan 2026). LumenFlow stores vendor-neutral skill sources in `.lumenflow/skills/` and projects them to each vendor surface via `pnpm lumenflow:integrate --client <x>`.
729
729
 
730
+ Agent plugins are a distribution on-ramp, not a replacement for these repo-level
731
+ projections or for the Software Delivery Pack runtime. Standalone projected
732
+ skills keep local names such as `design-first`, while plugin-installed Claude
733
+ skills use plugin-qualified names such as `/lumenflow:design-first`. If both
734
+ surfaces exist, prompts and handoff text must say which one they mean.
735
+ Installing a plugin gives the agent methodology and entrypoint guidance;
736
+ repo-level enforcement still requires `npx lumenflow init`,
737
+ `pnpm lumenflow:integrate`, or `pnpm lumenflow:integrate --sync`.
738
+
730
739
  ### Core skills (vendor-neutral)
731
740
 
732
741
  | Skill | Load before... |
@@ -752,6 +761,14 @@ A skill name written in prose does nothing — it must be **loaded** through the
752
761
  | Aider | `CONVENTIONS.md` | `/read CONVENTIONS.md` or `aider --read CONVENTIONS.md` |
753
762
  | Cline | `.clinerules` | Auto-loaded |
754
763
 
764
+ For plugin-distributed skills, prefer the vendor's plugin-qualified invocation
765
+ surface instead of rewriting all canonical skill names. Claude Code plugin
766
+ skills are namespaced as `/lumenflow:<skill>`. Codex plugin use should name the
767
+ installed `lumenflow` plugin or one of its bundled skills through Codex's `@`
768
+ plugin selection surface. Standalone projections remain valid until a future
769
+ explicit cleanup command such as `--plugin-only` exists and is run
770
+ intentionally.
771
+
755
772
  For vendor-specific setup details and per-vendor quirks, see:
756
773
 
757
774
  - Claude Code: [.claude/CLAUDE.md](.claude/CLAUDE.md)
@@ -40,12 +40,28 @@ Quick reference for AI agents working in LumenFlow projects.
40
40
  | Read WU spec first | Understand scope |
41
41
  | cd to worktree after claim | Isolation |
42
42
  | Write tests before code | TDD |
43
+ | Treat unread inbox signals as decisions | Prevent missed redirects |
43
44
  | Run wu:prep in the claimed workspace | Quality and lifecycle correctness |
44
45
  | Run wu:done from main | Complete WU |
45
46
  | Stay within code_paths | Scope discipline |
46
47
 
47
48
  ---
48
49
 
50
+ ## Coordination Signals
51
+
52
+ `wu:brief` includes an Inbox Snapshot when memory is available. Also check `mem:inbox`
53
+ after checkpoints and before `wu:prep`.
54
+
55
+ An unread signal is a decision point:
56
+
57
+ 1. Read it.
58
+ 2. Decide whether it changes, blocks, or does not affect the WU.
59
+ 3. Reply, acknowledge, or dismiss it before continuing.
60
+
61
+ Do not leave directed signals for `wu:done`; by then the coordination window has already passed.
62
+
63
+ ---
64
+
49
65
  ## Universal Safety Mechanisms
50
66
 
51
67
  ### Git Safety Wrapper
@@ -31,15 +31,15 @@ lumenflow init
31
31
 
32
32
  For popular AI coding assistants, LumenFlow provides **optional enhanced integrations** with deeper features like auto-detection, skills, and vendor-specific configurations.
33
33
 
34
- | Assistant | Config File | Auto-detected | Enhanced Features |
35
- | ----------- | ------------------------------ | ------------- | ------------------------------- |
36
- | Claude Code | `CLAUDE.md`, `.claude/` | Yes | Skills, agents, hooks, settings |
37
- | Cursor | `.cursor/rules/lumenflow.md` | Yes | Rules integration |
38
- | Windsurf | `.windsurf/rules/lumenflow.md` | Yes | Rules integration |
39
- | Cline | `.clinerules` | No | Rules file |
40
- | Codex | `AGENTS.md` (native) | No | Uses universal files directly |
41
- | Aider | `.aider.conf.yml` | No | Config file |
42
- | Antigravity | `AGENTS.md` (native) | Unknown | Research phase |
34
+ | Assistant | Config File | Auto-detected | Enhanced Features |
35
+ | ----------- | ------------------------------ | ------------- | ---------------------------------------------------------------- |
36
+ | Claude Code | `CLAUDE.md`, `.claude/` | Yes | Skills, agents, hooks, settings, A2A `signal:received` delivery |
37
+ | Cursor | `.cursor/rules/lumenflow.md` | Yes | Rules integration; A2A push deferred to `mem:watch` |
38
+ | Windsurf | `.windsurf/rules/lumenflow.md` | Yes | Rules integration; A2A push deferred to `mem:watch` |
39
+ | Cline | `.clinerules` | No | Rules file; poll `mem:inbox` for A2A signals |
40
+ | Codex | `AGENTS.md` (native) | No | Universal files directly; A2A push deferred to `mem:watch` |
41
+ | Aider | `.aider.conf.yml` | No | Config file; poll `mem:inbox` for A2A signals |
42
+ | Antigravity | `AGENTS.md` (native) | Unknown | Research phase |
43
43
 
44
44
  ---
45
45