@lumenflow/cli 5.0.2 → 5.1.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 (47) hide show
  1. package/dist/commands/integrate.js +9 -0
  2. package/dist/commands/integrate.js.map +1 -1
  3. package/dist/delegation-role-resolver.js +1 -1
  4. package/dist/delegation-role-resolver.js.map +1 -1
  5. package/dist/docs-generate-pack-reference.js +3 -15
  6. package/dist/docs-generate-pack-reference.js.map +1 -1
  7. package/dist/docs-sync.js +7 -3
  8. package/dist/docs-sync.js.map +1 -1
  9. package/dist/init-docs-scaffolder.js +18 -3
  10. package/dist/init-docs-scaffolder.js.map +1 -1
  11. package/dist/init-templates.js +399 -50
  12. package/dist/init-templates.js.map +1 -1
  13. package/dist/init.js +26 -6
  14. package/dist/init.js.map +1 -1
  15. package/dist/lumenflow-upgrade.js +286 -38
  16. package/dist/lumenflow-upgrade.js.map +1 -1
  17. package/dist/release.js +210 -2
  18. package/dist/release.js.map +1 -1
  19. package/dist/signal-middleware.js +23 -0
  20. package/dist/signal-middleware.js.map +1 -1
  21. package/dist/skills-projection.js +84 -0
  22. package/dist/skills-projection.js.map +1 -0
  23. package/dist/sync-templates.js +4 -4
  24. package/dist/sync-templates.js.map +1 -1
  25. package/dist/validate-agent-skills.js +4 -4
  26. package/dist/validate-agent-skills.js.map +1 -1
  27. package/dist/validate-agent-sync.js +108 -45
  28. package/dist/validate-agent-sync.js.map +1 -1
  29. package/dist/validate-skills-spec.js +2 -2
  30. package/dist/wu-done.js +1 -1
  31. package/dist/wu-done.js.map +1 -1
  32. package/dist/wu-spawn-prompt-builders.js +11 -34
  33. package/dist/wu-spawn-prompt-builders.js.map +1 -1
  34. package/package.json +11 -11
  35. package/packs/agent-runtime/package.json +1 -1
  36. package/packs/sidekick/package.json +1 -1
  37. package/packs/software-delivery/package.json +1 -1
  38. package/packs/software-delivery/src/config/schemas/lumenflow-config-schema-types.ts +26 -2
  39. package/packs/software-delivery/src/config/workspace-reader.ts +67 -2
  40. package/packs/software-delivery/src/constants/wu-paths-constants.ts +26 -0
  41. package/packs/software-delivery/src/domain/orchestration.constants.ts +7 -9
  42. package/packs/software-delivery/src/domain/orchestration.schemas.ts +1 -2
  43. package/packs/software-delivery/src/domain/orchestration.types.ts +0 -2
  44. package/packs/software-delivery/src/state/wu-paths.ts +1 -1
  45. package/templates/core/AGENTS.md.template +12 -8
  46. package/templates/core/LUMENFLOW.md.template +14 -9
  47. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +5 -0
@@ -29,6 +29,11 @@ import {
29
29
  DEFAULT_MAX_ESLINT_WARNINGS,
30
30
  DEFAULT_MIN_COVERAGE,
31
31
  } from '../../constants/gate-constants.js';
32
+ import {
33
+ AGENT_NAMES,
34
+ MANDATORY_AGENT_NAMES,
35
+ MANDATORY_TRIGGERS,
36
+ } from '../../domain/orchestration.constants.js';
32
37
 
33
38
  const DEFAULT_LAYOUT = DOCS_LAYOUT_PRESETS.simple;
34
39
 
@@ -76,7 +81,7 @@ export const DIRECTORIES_DEFAULTS: DirectoriesConfig = {
76
81
  initiativesDir: `${DEFAULT_LAYOUT.tasks}/initiatives`,
77
82
  backlogPath: `${DEFAULT_LAYOUT.tasks}/backlog.md`,
78
83
  statusPath: `${DEFAULT_LAYOUT.tasks}/status.md`,
79
- skillsDir: '.claude/skills',
84
+ skillsDir: '.lumenflow/skills',
80
85
  agentsDir: '.claude/agents',
81
86
  adrDir: DEFAULT_LAYOUT.adrDir,
82
87
  plansDir: `${DEFAULT_LAYOUT.operations}/plans`,
@@ -342,16 +347,35 @@ export const MEMORY_DEFAULTS: MemoryConfig = {
342
347
  };
343
348
 
344
349
  // ---------------------------------------------------------------------------
345
- // Agents (narrow — only defaultClient, which many cohorts need)
350
+ // Agents
346
351
  // ---------------------------------------------------------------------------
347
352
 
353
+ export interface MandatoryAgentsConfig {
354
+ names: string[];
355
+ triggers: Record<string, string[]>;
356
+ [extra: string]: unknown;
357
+ }
358
+
348
359
  export interface AgentsConfig {
349
360
  defaultClient: string;
361
+ roster: string[];
362
+ mandatory: MandatoryAgentsConfig;
350
363
  [extra: string]: unknown;
351
364
  }
352
365
 
366
+ function cloneMandatoryTriggersDefaults(): Record<string, string[]> {
367
+ return Object.fromEntries(
368
+ Object.entries(MANDATORY_TRIGGERS).map(([agentName, patterns]) => [agentName, [...patterns]]),
369
+ );
370
+ }
371
+
353
372
  export const AGENTS_DEFAULTS: AgentsConfig = {
354
373
  defaultClient: LUMENFLOW_CLIENT_IDS.CLAUDE_CODE,
374
+ roster: [...AGENT_NAMES],
375
+ mandatory: {
376
+ names: [...MANDATORY_AGENT_NAMES],
377
+ triggers: cloneMandatoryTriggersDefaults(),
378
+ },
355
379
  };
356
380
 
357
381
  // ---------------------------------------------------------------------------
@@ -172,6 +172,30 @@ function mergeSimple<T>(defaults: T, overrides: unknown): T {
172
172
  return { ...defaults };
173
173
  }
174
174
 
175
+ function isObjectRecord(value: unknown): value is Record<string, unknown> {
176
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
177
+ }
178
+
179
+ function isStringArray(value: unknown): value is string[] {
180
+ return Array.isArray(value) && value.every((item) => typeof item === 'string');
181
+ }
182
+
183
+ function cloneStringArrayRecord(record: Record<string, string[]>): Record<string, string[]> {
184
+ return Object.fromEntries(Object.entries(record).map(([key, values]) => [key, [...values]]));
185
+ }
186
+
187
+ function readStringArrayRecord(value: unknown): Record<string, string[]> {
188
+ if (!isObjectRecord(value)) {
189
+ return {};
190
+ }
191
+
192
+ return Object.fromEntries(
193
+ Object.entries(value).flatMap(([key, entryValue]) =>
194
+ isStringArray(entryValue) ? [[key, [...entryValue]]] : [],
195
+ ),
196
+ );
197
+ }
198
+
175
199
  function mergeTelemetry(overrides: Partial<TelemetryConfig> | undefined): TelemetryConfig {
176
200
  if (!overrides) {
177
201
  return { methodology: { ...TELEMETRY_DEFAULTS.methodology } };
@@ -189,6 +213,47 @@ function pickEnum<T extends string>(value: unknown, allowed: readonly T[], fallb
189
213
  : fallback;
190
214
  }
191
215
 
216
+ function cloneAgentsDefaults(): AgentsConfig {
217
+ return {
218
+ ...AGENTS_DEFAULTS,
219
+ roster: [...AGENTS_DEFAULTS.roster],
220
+ mandatory: {
221
+ ...AGENTS_DEFAULTS.mandatory,
222
+ names: [...AGENTS_DEFAULTS.mandatory.names],
223
+ triggers: cloneStringArrayRecord(AGENTS_DEFAULTS.mandatory.triggers),
224
+ },
225
+ };
226
+ }
227
+
228
+ function mergeAgents(overrides: unknown): AgentsConfig {
229
+ if (!isObjectRecord(overrides)) {
230
+ return cloneAgentsDefaults();
231
+ }
232
+
233
+ const defaults = cloneAgentsDefaults();
234
+ const { defaultClient, roster, mandatory: overrideMandatory, ...flatOverrides } = overrides;
235
+ const mandatoryOverrides = isObjectRecord(overrideMandatory) ? overrideMandatory : {};
236
+
237
+ return {
238
+ ...defaults,
239
+ ...flatOverrides,
240
+ defaultClient:
241
+ typeof defaultClient === 'string' ? defaultClient : AGENTS_DEFAULTS.defaultClient,
242
+ roster: isStringArray(roster) ? [...roster] : [...AGENTS_DEFAULTS.roster],
243
+ mandatory: {
244
+ ...defaults.mandatory,
245
+ ...mandatoryOverrides,
246
+ names: isStringArray(mandatoryOverrides['names'])
247
+ ? [...mandatoryOverrides['names']]
248
+ : [...AGENTS_DEFAULTS.mandatory.names],
249
+ triggers: {
250
+ ...cloneStringArrayRecord(AGENTS_DEFAULTS.mandatory.triggers),
251
+ ...readStringArrayRecord(mandatoryOverrides['triggers']),
252
+ },
253
+ },
254
+ };
255
+ }
256
+
192
257
  /**
193
258
  * Return the fully-typed pack-local `LumenflowConfig` for the workspace rooted
194
259
  * at `cwd`.
@@ -230,7 +295,7 @@ export function getConfig(cwd: string): LumenflowConfig {
230
295
  memory: mergeSimple<MemoryConfig>(MEMORY_DEFAULTS, section['memory']),
231
296
  ui: mergeSimple<UiConfig>(UI_DEFAULTS, section['ui']),
232
297
  yaml: mergeSimple<YamlConfig>(YAML_DEFAULTS, section['yaml']),
233
- agents: mergeSimple<AgentsConfig>(AGENTS_DEFAULTS, section['agents']),
298
+ agents: mergeAgents(section['agents']),
234
299
  experimental: mergeSimple<ExperimentalConfig>(EXPERIMENTAL_DEFAULTS, section['experimental']),
235
300
  cleanup: mergeSimple<CleanupConfig>(CLEANUP_DEFAULTS, section['cleanup']),
236
301
  telemetry: mergeTelemetry(section['telemetry'] as Partial<TelemetryConfig> | undefined),
@@ -275,7 +340,7 @@ function cloneDefaults(): LumenflowConfig {
275
340
  memory: { ...MEMORY_DEFAULTS },
276
341
  ui: { ...UI_DEFAULTS },
277
342
  yaml: { ...YAML_DEFAULTS },
278
- agents: { ...AGENTS_DEFAULTS },
343
+ agents: cloneAgentsDefaults(),
279
344
  experimental: { ...EXPERIMENTAL_DEFAULTS },
280
345
  cleanup: { ...CLEANUP_DEFAULTS },
281
346
  telemetry: { methodology: { ...TELEMETRY_DEFAULTS.methodology } },
@@ -82,6 +82,32 @@ export const DIRECTORIES = {
82
82
  STATUS_PATH: `${DEFAULT_DOCS_PATHS.tasks}/status.md`,
83
83
  };
84
84
 
85
+ /**
86
+ * Shared agent/client surface paths.
87
+ *
88
+ * Keeps vendor overlay and shared projection roots centralized so runtime code
89
+ * does not scatter hardcoded path literals through CLI/core packages.
90
+ */
91
+ export const AGENT_SURFACES = {
92
+ /** Claude-projected skills directory */
93
+ CLAUDE_SKILLS_DIR: '.claude/skills',
94
+
95
+ /** Claude agent overlay directory */
96
+ CLAUDE_AGENTS_DIR: '.claude/agents',
97
+
98
+ /** Shared cross-vendor projected skills directory */
99
+ SHARED_SKILLS_DIR: '.agents/skills',
100
+
101
+ /** Codex agent overlay directory */
102
+ CODEX_AGENTS_DIR: '.codex/agents',
103
+
104
+ /** Gemini projected skills directory */
105
+ GEMINI_SKILLS_DIR: '.gemini/skills',
106
+
107
+ /** Gemini agent overlay directory */
108
+ GEMINI_AGENTS_DIR: '.gemini/agents',
109
+ };
110
+
85
111
  /**
86
112
  * Build artifact cleanup globs
87
113
  *
@@ -47,8 +47,12 @@ export type Lane = (typeof LANES)[number];
47
47
  * Known agent names in the orchestration system.
48
48
  * Includes both mandatory (Tier 1) and suggested (Tier 2) agents.
49
49
  *
50
- * Note: These are LumenFlow framework agents defined in .claude/agents/.
51
- * Application-specific agents should be configured separately.
50
+ * Note: These are the framework's vendor-neutral default aliases. Vendor
51
+ * overlays may materialize them in different native surfaces, and
52
+ * application-specific agents should still be configured separately.
53
+ *
54
+ * v2 roster refresh: the default set removes `lumenflow-doc-sync` and adds
55
+ * `initiative-architect`.
52
56
  */
53
57
  export const AGENT_NAMES = [
54
58
  'general-purpose',
@@ -57,12 +61,9 @@ export const AGENT_NAMES = [
57
61
  'code-reviewer',
58
62
  'bug-triage',
59
63
  'lumenflow-enforcer',
60
- 'lumenflow-doc-sync',
64
+ 'initiative-architect',
61
65
  ] as const;
62
66
 
63
- /** Type for agent names */
64
- export type AgentName = (typeof AGENT_NAMES)[number];
65
-
66
67
  /**
67
68
  * Alert severity levels for dashboard display.
68
69
  * HIGH = action required immediately
@@ -127,9 +128,6 @@ export type UserChoiceOption = (typeof USER_CHOICE_OPTIONS)[number];
127
128
  */
128
129
  export const MANDATORY_AGENT_NAMES = [] as const;
129
130
 
130
- /** Type for mandatory agent names */
131
- export type MandatoryAgentName = (typeof MANDATORY_AGENT_NAMES)[number];
132
-
133
131
  /**
134
132
  * Mandatory agent triggers - glob patterns that indicate when agents must be invoked.
135
133
  * Uses minimatch patterns (NOT regex) for file path matching.
@@ -15,7 +15,6 @@
15
15
  import { z } from 'zod';
16
16
  import {
17
17
  LANES,
18
- AGENT_NAMES,
19
18
  SEVERITY_LEVELS,
20
19
  AGENT_RESULT_STATUSES,
21
20
  TIMELINE_EVENT_TYPES,
@@ -38,7 +37,7 @@ const LongestRunningSchema = z.object({
38
37
  */
39
38
  const PendingMandatorySchema = z.object({
40
39
  wuId: z.string().min(1),
41
- agent: z.enum(AGENT_NAMES),
40
+ agent: z.string().min(1),
42
41
  });
43
42
 
44
43
  /**
@@ -28,13 +28,11 @@ import type {
28
28
  // Re-export constant-derived types for convenience
29
29
  export type {
30
30
  Lane,
31
- AgentName,
32
31
  SeverityLevel,
33
32
  AgentResultStatus,
34
33
  TimelineEventType,
35
34
  EventSeverityLevel,
36
35
  UserChoiceOption,
37
- MandatoryAgentName,
38
36
  } from './orchestration.constants.js';
39
37
 
40
38
  // Re-export const values as well
@@ -67,7 +67,7 @@ const FALLBACK_DIRECTORIES: WorkspaceDirectories = {
67
67
  initiativesDir: 'docs/operations/tasks/initiatives',
68
68
  backlogPath: 'docs/operations/tasks/backlog.md',
69
69
  statusPath: 'docs/operations/tasks/status.md',
70
- skillsDir: '.claude/skills',
70
+ skillsDir: '.lumenflow/skills',
71
71
  agentsDir: '.claude/agents',
72
72
  adrDir: 'docs/adr',
73
73
  plansDir: 'docs/operations/plans',
@@ -204,14 +204,18 @@ LumenFlow enforces safety at the repository level via git wrappers and hooks. Fo
204
204
 
205
205
  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
206
 
207
- | Vendor | Skill / rules surface | Invocation |
208
- | ------------ | --------------------------------------- | -------------------------------------------------------- |
209
- | Claude Code | `.claude/skills/` + `.claude/CLAUDE.md` | `Skill` tool call, or `/skill <name>` in interactive CLI |
210
- | OpenAI Codex | `.codex/skills/` or repo `skills/` | `/skills`, `$<name>` mention, or implicit |
211
- | Cursor | `.cursor/rules/` + agent skills | `/skills` or auto-discovery |
212
- | Windsurf | `.windsurf/rules/` + Cascade skills | Auto-discovery; workflows via `/<workflow-name>` |
213
- | Aider | `CONVENTIONS.md` | `/read CONVENTIONS.md` or `aider --read CONVENTIONS.md` |
214
- | Cline | `.clinerules` | Auto-loaded |
207
+ | Vendor | Skill / rules surface | Invocation |
208
+ | ------------ | --------------------------------------------------- | ---------------------------------------------------------------------- |
209
+ | Claude Code | `.claude/skills/` + `.claude/CLAUDE.md` | `Skill` tool call, or `/skill <name>` in interactive CLI |
210
+ | OpenAI Codex | `AGENTS.md` + `.agents/skills/` + `.codex/agents/` | `/skills`, `$<name>` mention, implicit skills, explicit subagent usage |
211
+ | Cursor | `.cursor/rules/` + `.agents/skills/` | `/skills` or auto-discovery |
212
+ | Windsurf | `.windsurf/rules/` + `.agents/skills/` | Auto-discovery; workflows via `/<workflow-name>` |
213
+ | Aider | `CONVENTIONS.md` | `/read CONVENTIONS.md` or `aider --read CONVENTIONS.md` |
214
+ | Cline | `.clinerules` | Auto-loaded |
215
+
216
+ Shared cross-vendor surfaces: `AGENTS.md` and `.agents/skills/`.
217
+ Vendor-specific overlays: `.claude/agents/`, `.codex/agents/`, `.cursor/rules/`, and `.windsurf/rules/`.
218
+ For Codex specifically, `.codex/agents/*.toml` are explicit-only subagent overlays; Codex will not auto-match them by description.
215
219
 
216
220
  A skill named in prose does nothing — load it through the vendor's invocation before the work it covers. See [LUMENFLOW.md "Skills & Agents"](LUMENFLOW.md#skills--agents) for the canonical skill list.
217
221
 
@@ -761,15 +761,20 @@ For vendor-specific setup details and per-vendor quirks, see:
761
761
 
762
762
  ### Agents
763
763
 
764
- Pre-configured agent definitions in `.claude/agents/`:
764
+ Recommended framework roster (vendor-neutral aliases):
765
765
 
766
- | Agent | Purpose |
767
- | ----------------- | -------------------------- |
768
- | `general-purpose` | Standard WU implementation |
769
- | `lumenflow-pm` | Backlog & lifecycle |
770
- | `test-engineer` | TDD, coverage |
771
- | `code-reviewer` | Quality checks |
772
- | `bug-triage` | Bug classification |
766
+ | Agent | Purpose |
767
+ | ---------------------- | ------------------------------------- |
768
+ | `general-purpose` | Standard WU implementation |
769
+ | `lumenflow-pm` | Backlog & lifecycle |
770
+ | `test-engineer` | TDD, coverage |
771
+ | `code-reviewer` | Quality checks |
772
+ | `bug-triage` | Bug classification |
773
+ | `lumenflow-enforcer` | Workflow compliance and gates |
774
+ | `initiative-architect` | Initiative planning and decomposition |
775
+
776
+ Client-specific overlays may implement these aliases in different native surfaces such as
777
+ `.claude/agents/`, `.codex/agents/`, or vendor rule/config directories.
773
778
 
774
779
  Generate handoff prompts (prompt-only, execution is a separate step): `pnpm wu:brief --id WU-XXX --client <client>`
775
780
  Record explicit delegation lineage when needed: `pnpm wu:delegate --id WU-XXX --parent-wu WU-YYY --client <client>`
@@ -797,5 +802,5 @@ Durable artifacts carry `requested_role` (from the orchestrator) and `actual_rol
797
802
  - [.lumenflow/constraints.md](.lumenflow/constraints.md) -- Non-negotiable rules and forbidden commands
798
803
  - [WU Sizing Guide]({{DOCS_OPERATIONS_PATH}}/_frameworks/lumenflow/wu-sizing-guide.md) -- Scoping work without needless fragmentation
799
804
  - [ADR-014: Typed Agent-Role Contract](docs/09-architecture-decisions/ADR-014-typed-agent-role-contract.md) — Canonical orchestration role vocabulary
800
- - [Skills Index](.claude/skills/INDEX.md)
805
+ - [Skills Index](.lumenflow/skills/INDEX.md)
801
806
  - [Agents README](.claude/agents/README.md)
@@ -146,6 +146,10 @@ These surfaces already assemble the objective, scope, code paths, tests, recover
146
146
  constraints block, and evidence metadata. Do not prepend or append a second wrapper block around
147
147
  them.
148
148
 
149
+ The role aliases referenced by these handoffs are vendor-neutral framework names (`general-purpose`,
150
+ `lumenflow-pm`, `initiative-architect`, and so on). Client-specific overlays may implement those
151
+ aliases differently, but the orchestration brief should keep the shared alias vocabulary intact.
152
+
149
153
  If you are building a fully custom or experimental prompt outside those canonical surfaces, use
150
154
  this structure:
151
155
 
@@ -214,6 +218,7 @@ Before spawning:
214
218
 
215
219
  - Confirm WU status and lane availability
216
220
  - Ensure worktree exists (or claim first)
221
+ - Use the shared framework alias vocabulary in the brief, not vendor-specific display names
217
222
  - Provide explicit code_paths and tests
218
223
  - Require `mem:checkpoint` at 50+ tool calls
219
224
  - Require `mem:signal` for milestones