@lumenflow/cli 5.3.2 → 5.5.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.
- package/README.md +20 -18
- package/dist/agent-session.js +21 -0
- package/dist/agent-session.js.map +1 -1
- package/dist/commands/integrate.js +25 -1
- package/dist/commands/integrate.js.map +1 -1
- package/dist/gate-defaults.js +154 -9
- package/dist/gate-defaults.js.map +1 -1
- package/dist/gate-registry.js.map +1 -1
- package/dist/gates-runners.js +358 -0
- package/dist/gates-runners.js.map +1 -1
- package/dist/gates.js +347 -3
- package/dist/gates.js.map +1 -1
- package/dist/hooks/enforcement-generator.js +14 -8
- package/dist/hooks/enforcement-generator.js.map +1 -1
- package/dist/hooks/enforcement-sync.js +2 -1
- package/dist/hooks/enforcement-sync.js.map +1 -1
- package/dist/hooks/generators/index.js +1 -0
- package/dist/hooks/generators/index.js.map +1 -1
- package/dist/hooks/generators/signal-received.js +4 -0
- package/dist/hooks/generators/signal-received.js.map +1 -0
- package/dist/mem-converged.js +101 -0
- package/dist/mem-converged.js.map +1 -0
- package/dist/mem-inbox.js +85 -22
- package/dist/mem-inbox.js.map +1 -1
- package/dist/mem-roster.js +11 -1
- package/dist/mem-roster.js.map +1 -1
- package/dist/mem-signal.js +162 -16
- package/dist/mem-signal.js.map +1 -1
- package/dist/mem-watch.js +207 -0
- package/dist/mem-watch.js.map +1 -0
- package/dist/metrics-cli.js +19 -2
- package/dist/metrics-cli.js.map +1 -1
- package/dist/metrics-snapshot.js +25 -2
- package/dist/metrics-snapshot.js.map +1 -1
- package/dist/public-manifest.js +14 -0
- package/dist/public-manifest.js.map +1 -1
- package/dist/session-cross-link.js +14 -2
- package/dist/session-cross-link.js.map +1 -1
- package/dist/sidecar-manager.js +25 -0
- package/dist/sidecar-manager.js.map +1 -1
- package/dist/signal-hook.js +351 -0
- package/dist/signal-hook.js.map +1 -0
- package/dist/wu-done-gates.js +112 -3
- package/dist/wu-done-gates.js.map +1 -1
- package/dist/wu-done.js +30 -6
- package/dist/wu-done.js.map +1 -1
- package/dist/wu-prep.js +185 -2
- package/dist/wu-prep.js.map +1 -1
- package/dist/wu-spawn-prompt-builders.js.map +1 -1
- package/dist/wu-spawn-strategy-resolver.js +46 -4
- package/dist/wu-spawn-strategy-resolver.js.map +1 -1
- package/package.json +13 -11
- package/packs/agent-runtime/auto-session-integration.ts +14 -0
- package/packs/agent-runtime/package.json +1 -1
- package/packs/agent-runtime/session-schema.ts +44 -0
- package/packs/sidekick/package.json +1 -1
- package/packs/software-delivery/manifest.ts +3 -0
- package/packs/software-delivery/manifest.yaml +7 -0
- package/packs/software-delivery/package.json +1 -1
- package/packs/software-delivery/src/constants/wu-cli-constants.ts +12 -0
- package/packs/software-delivery/tool-impl/memory-tools.ts +56 -1
- package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +1 -0
- package/templates/core/AGENTS.md.template +98 -8
- package/templates/core/LUMENFLOW.md.template +197 -19
- package/templates/core/ai/onboarding/agent-invocation-guide.md.template +0 -5
- package/templates/core/ai/onboarding/agent-safety-card.md.template +63 -1
- package/templates/core/ai/onboarding/initiative-orchestration.md.template +4 -0
- package/templates/core/ai/onboarding/release-process.md.template +7 -7
- package/templates/core/ai/onboarding/vendor-support.md.template +74 -10
- package/templates/vendors/claude/.claude/skills/frontend-design/SKILL.md.template +1 -1
- package/templates/vendors/claude/.claude/skills/wu-lifecycle/SKILL.md.template +28 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumenflow/cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "Command-line interface for LumenFlow workflow framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lumenflow",
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
"lumenflow-validate": "./dist/validate.js",
|
|
99
99
|
"mem-checkpoint": "./dist/mem-checkpoint.js",
|
|
100
100
|
"mem-cleanup": "./dist/mem-cleanup.js",
|
|
101
|
+
"mem-converged": "./dist/mem-converged.js",
|
|
101
102
|
"mem-context": "./dist/mem-context.js",
|
|
102
103
|
"mem-create": "./dist/mem-create.js",
|
|
103
104
|
"mem-delete": "./dist/mem-delete.js",
|
|
@@ -111,6 +112,7 @@
|
|
|
111
112
|
"mem-start": "./dist/mem-start.js",
|
|
112
113
|
"mem-summarize": "./dist/mem-summarize.js",
|
|
113
114
|
"mem-triage": "./dist/mem-triage.js",
|
|
115
|
+
"mem-watch": "./dist/mem-watch.js",
|
|
114
116
|
"metrics": "./dist/metrics-cli.js",
|
|
115
117
|
"metrics-snapshot": "./dist/metrics-snapshot.js",
|
|
116
118
|
"onboard": "./dist/onboard.js",
|
|
@@ -198,16 +200,16 @@
|
|
|
198
200
|
"xstate": "^5.28.0",
|
|
199
201
|
"yaml": "^2.8.2",
|
|
200
202
|
"zod": "^4.3.6",
|
|
201
|
-
"@lumenflow/agent": "5.
|
|
202
|
-
"@lumenflow/
|
|
203
|
-
"@lumenflow/
|
|
204
|
-
"@lumenflow/initiatives": "5.
|
|
205
|
-
"@lumenflow/
|
|
206
|
-
"@lumenflow/
|
|
207
|
-
"@lumenflow/
|
|
208
|
-
"@lumenflow/
|
|
209
|
-
"@lumenflow/
|
|
210
|
-
"@lumenflow/packs-software-delivery": "^5.
|
|
203
|
+
"@lumenflow/agent": "5.5.0",
|
|
204
|
+
"@lumenflow/host": "^5.5.0",
|
|
205
|
+
"@lumenflow/control-plane-sdk": "5.5.0",
|
|
206
|
+
"@lumenflow/initiatives": "5.5.0",
|
|
207
|
+
"@lumenflow/core": "5.5.0",
|
|
208
|
+
"@lumenflow/kernel": "5.5.0",
|
|
209
|
+
"@lumenflow/packs-agent-runtime": "^5.5.0",
|
|
210
|
+
"@lumenflow/metrics": "5.5.0",
|
|
211
|
+
"@lumenflow/memory": "5.5.0",
|
|
212
|
+
"@lumenflow/packs-software-delivery": "^5.5.0"
|
|
211
213
|
},
|
|
212
214
|
"devDependencies": {
|
|
213
215
|
"@vitest/coverage-v8": "^4.0.18",
|
|
@@ -83,6 +83,10 @@ interface SessionFileData {
|
|
|
83
83
|
/** ADR-014 extension 2 — which skill bundle the agent identifies as carrying (WU-2754). */
|
|
84
84
|
specialty_profile?: string;
|
|
85
85
|
display_name?: string;
|
|
86
|
+
/** Stable explicit A2A reader identity. Format hint: <owner>:<role>:<purpose>. */
|
|
87
|
+
agent_identity?: string;
|
|
88
|
+
/** Reserved cloud workspace/tenant scope slot; unused by local runtime. */
|
|
89
|
+
tenant_id?: string;
|
|
86
90
|
/** ADR-014 extension 2 — parent delegation registry reference (WU-2754). */
|
|
87
91
|
delegation_id?: string;
|
|
88
92
|
}
|
|
@@ -455,6 +459,10 @@ interface StartSessionOptions {
|
|
|
455
459
|
/** ADR-014 specialty_profile for this session (e.g. 'delivery'). */
|
|
456
460
|
specialtyProfile?: string;
|
|
457
461
|
displayName?: string;
|
|
462
|
+
/** Explicit stable A2A reader identity. Format hint: <owner>:<role>:<purpose>. */
|
|
463
|
+
agentIdentity?: string;
|
|
464
|
+
/** Reserved cloud workspace/tenant scope slot; unused by local runtime. */
|
|
465
|
+
tenantId?: string;
|
|
458
466
|
/** Parent delegation-registry record reference (dlg-XXXX). */
|
|
459
467
|
delegationId?: string;
|
|
460
468
|
}
|
|
@@ -511,6 +519,8 @@ export async function startSessionForWU(options: StartSessionOptions): Promise<S
|
|
|
511
519
|
lifecycleRole,
|
|
512
520
|
specialtyProfile,
|
|
513
521
|
displayName,
|
|
522
|
+
agentIdentity,
|
|
523
|
+
tenantId,
|
|
514
524
|
delegationId,
|
|
515
525
|
} = options;
|
|
516
526
|
|
|
@@ -542,6 +552,8 @@ export async function startSessionForWU(options: StartSessionOptions): Promise<S
|
|
|
542
552
|
lifecycle_role: lifecycleRole,
|
|
543
553
|
specialty_profile: specialtyProfile,
|
|
544
554
|
display_name: displayName,
|
|
555
|
+
agent_identity: agentIdentity,
|
|
556
|
+
tenant_id: tenantId,
|
|
545
557
|
delegation_id: delegationId,
|
|
546
558
|
});
|
|
547
559
|
const resolvedDisplayName = roleAxes.display_name ?? acquireDisplayName(workspaceRoot, sessionId);
|
|
@@ -564,6 +576,8 @@ export async function startSessionForWU(options: StartSessionOptions): Promise<S
|
|
|
564
576
|
lifecycle_role: roleAxes.lifecycle_role,
|
|
565
577
|
specialty_profile: roleAxes.specialty_profile,
|
|
566
578
|
display_name: resolvedDisplayName,
|
|
579
|
+
...(roleAxes.agent_identity ? { agent_identity: roleAxes.agent_identity } : {}),
|
|
580
|
+
...(roleAxes.tenant_id ? { tenant_id: roleAxes.tenant_id } : {}),
|
|
567
581
|
...(roleAxes.delegation_id ? { delegation_id: roleAxes.delegation_id } : {}),
|
|
568
582
|
};
|
|
569
583
|
|
|
@@ -70,6 +70,7 @@ export const DISPLAY_NAME_POOL_RELATIVE_PATH = '.lumenflow/agents/display-name-p
|
|
|
70
70
|
export const DISPLAY_NAME_RESERVATIONS_RELATIVE_PATH =
|
|
71
71
|
'.lumenflow/state/display-name-reservations.jsonl';
|
|
72
72
|
export const DISPLAY_NAME_RESERVATION_TTL_HOURS = 12;
|
|
73
|
+
export const AGENT_IDENTITY_MIN_LENGTH = 3;
|
|
73
74
|
|
|
74
75
|
/** Regex for delegation_id references back into delegation registry. */
|
|
75
76
|
export const DELEGATION_ID_PATTERN = /^dlg-[0-9a-f]{4}$/;
|
|
@@ -93,6 +94,14 @@ export const SessionRoleAxesSchema = z.object({
|
|
|
93
94
|
.optional(),
|
|
94
95
|
});
|
|
95
96
|
|
|
97
|
+
const AgentIdentitySchema = z
|
|
98
|
+
.string()
|
|
99
|
+
.trim()
|
|
100
|
+
.min(AGENT_IDENTITY_MIN_LENGTH, {
|
|
101
|
+
message: `agent_identity must be at least ${AGENT_IDENTITY_MIN_LENGTH} characters`,
|
|
102
|
+
});
|
|
103
|
+
const TenantIdSchema = z.string().trim().min(1, { message: 'tenant_id must be non-empty' });
|
|
104
|
+
|
|
96
105
|
/**
|
|
97
106
|
* Base session schema — shared fields across v1 and v2.
|
|
98
107
|
*
|
|
@@ -104,6 +113,8 @@ const SessionRecordBaseSchema = z.object({
|
|
|
104
113
|
session_id: z.string().min(1),
|
|
105
114
|
wu_id: z.string().min(1),
|
|
106
115
|
started: z.string().min(1),
|
|
116
|
+
agent_identity: AgentIdentitySchema.optional(),
|
|
117
|
+
tenant_id: TenantIdSchema.optional(),
|
|
107
118
|
});
|
|
108
119
|
|
|
109
120
|
/**
|
|
@@ -172,11 +183,15 @@ export function withV2RoleDefaults(input: {
|
|
|
172
183
|
specialty_profile?: string | null;
|
|
173
184
|
display_name?: string | null;
|
|
174
185
|
delegation_id?: string | null;
|
|
186
|
+
agent_identity?: string | null;
|
|
187
|
+
tenant_id?: string | null;
|
|
175
188
|
}): {
|
|
176
189
|
lifecycle_role: string;
|
|
177
190
|
specialty_profile: string;
|
|
178
191
|
display_name?: string;
|
|
179
192
|
delegation_id?: string;
|
|
193
|
+
agent_identity?: string;
|
|
194
|
+
tenant_id?: string;
|
|
180
195
|
} {
|
|
181
196
|
const lifecycle_role =
|
|
182
197
|
typeof input.lifecycle_role === 'string' && input.lifecycle_role.trim().length > 0
|
|
@@ -194,11 +209,14 @@ export function withV2RoleDefaults(input: {
|
|
|
194
209
|
typeof input.display_name === 'string' && input.display_name.trim().length > 0
|
|
195
210
|
? input.display_name.trim()
|
|
196
211
|
: undefined;
|
|
212
|
+
const identityFields = normalizeOptionalSessionIdentityFields(input);
|
|
197
213
|
const out: {
|
|
198
214
|
lifecycle_role: string;
|
|
199
215
|
specialty_profile: string;
|
|
200
216
|
display_name?: string;
|
|
201
217
|
delegation_id?: string;
|
|
218
|
+
agent_identity?: string;
|
|
219
|
+
tenant_id?: string;
|
|
202
220
|
} = {
|
|
203
221
|
lifecycle_role,
|
|
204
222
|
specialty_profile,
|
|
@@ -209,6 +227,32 @@ export function withV2RoleDefaults(input: {
|
|
|
209
227
|
if (delegation_id) {
|
|
210
228
|
out.delegation_id = delegation_id;
|
|
211
229
|
}
|
|
230
|
+
if (identityFields.agent_identity) {
|
|
231
|
+
out.agent_identity = identityFields.agent_identity;
|
|
232
|
+
}
|
|
233
|
+
if (identityFields.tenant_id) {
|
|
234
|
+
out.tenant_id = identityFields.tenant_id;
|
|
235
|
+
}
|
|
236
|
+
return out;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function normalizeOptionalSessionIdentityFields(input: {
|
|
240
|
+
agent_identity?: string | null;
|
|
241
|
+
tenant_id?: string | null;
|
|
242
|
+
}): {
|
|
243
|
+
agent_identity?: string;
|
|
244
|
+
tenant_id?: string;
|
|
245
|
+
} {
|
|
246
|
+
const out: {
|
|
247
|
+
agent_identity?: string;
|
|
248
|
+
tenant_id?: string;
|
|
249
|
+
} = {};
|
|
250
|
+
if (typeof input.agent_identity === 'string' && input.agent_identity.trim().length > 0) {
|
|
251
|
+
out.agent_identity = AgentIdentitySchema.parse(input.agent_identity);
|
|
252
|
+
}
|
|
253
|
+
if (typeof input.tenant_id === 'string' && input.tenant_id.trim().length > 0) {
|
|
254
|
+
out.tenant_id = TenantIdSchema.parse(input.tenant_id);
|
|
255
|
+
}
|
|
212
256
|
return out;
|
|
213
257
|
}
|
|
214
258
|
|
|
@@ -140,6 +140,7 @@ const MEM_DELETE_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memDeleteTool';
|
|
|
140
140
|
const MEM_EXPORT_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memExportTool';
|
|
141
141
|
const MEM_INBOX_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memInboxTool';
|
|
142
142
|
const MEM_SIGNAL_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memSignalTool';
|
|
143
|
+
const MEM_CONVERGED_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memConvergedTool';
|
|
143
144
|
const MEM_SUMMARIZE_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memSummarizeTool';
|
|
144
145
|
const MEM_TRIAGE_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memTriageTool';
|
|
145
146
|
const MEM_RECOVER_TOOL_ENTRY = 'tool-impl/memory-tools.ts#memRecoverTool';
|
|
@@ -245,6 +246,7 @@ const TOOL_PERMISSIONS = {
|
|
|
245
246
|
'wu:validate': 'read',
|
|
246
247
|
'mem:checkpoint': 'write',
|
|
247
248
|
'mem:cleanup': 'write',
|
|
249
|
+
'mem:converged': 'read',
|
|
248
250
|
'mem:context': 'read',
|
|
249
251
|
'mem:create': 'write',
|
|
250
252
|
'mem:delete': 'write',
|
|
@@ -371,6 +373,7 @@ const TOOL_ENTRY_OVERRIDES: Partial<Record<ToolName, string>> = {
|
|
|
371
373
|
'mem:export': MEM_EXPORT_TOOL_ENTRY,
|
|
372
374
|
'mem:inbox': MEM_INBOX_TOOL_ENTRY,
|
|
373
375
|
'mem:signal': MEM_SIGNAL_TOOL_ENTRY,
|
|
376
|
+
'mem:converged': MEM_CONVERGED_TOOL_ENTRY,
|
|
374
377
|
'mem:summarize': MEM_SUMMARIZE_TOOL_ENTRY,
|
|
375
378
|
'mem:triage': MEM_TRIAGE_TOOL_ENTRY,
|
|
376
379
|
'mem:recover': MEM_RECOVER_TOOL_ENTRY,
|
|
@@ -244,6 +244,13 @@ tools:
|
|
|
244
244
|
entry: tool-impl/memory-tools.ts#memCleanupTool
|
|
245
245
|
permission: write
|
|
246
246
|
required_scopes: *softwareDeliveryWriteScopes
|
|
247
|
+
- name: mem:converged
|
|
248
|
+
entry: tool-impl/memory-tools.ts#memConvergedTool
|
|
249
|
+
permission: read
|
|
250
|
+
required_scopes:
|
|
251
|
+
- type: path
|
|
252
|
+
pattern: '**'
|
|
253
|
+
access: read
|
|
247
254
|
- name: mem:context
|
|
248
255
|
entry: tool-impl/memory-tools.ts#memContextTool
|
|
249
256
|
permission: read
|
|
@@ -87,6 +87,10 @@ export const SCRIPTS = {
|
|
|
87
87
|
LINT: 'lint',
|
|
88
88
|
TEST: 'test',
|
|
89
89
|
TEST_UNIT: 'test:unit',
|
|
90
|
+
/** WU-2927: opt-in local-prep integration-test gate script */
|
|
91
|
+
TEST_INTEGRATION: 'test:integration',
|
|
92
|
+
/** WU-2927: opt-in local-prep e2e-smoke gate script */
|
|
93
|
+
TEST_E2E: 'test:e2e',
|
|
90
94
|
BUILD: 'build',
|
|
91
95
|
FORMAT: 'format',
|
|
92
96
|
FORMAT_CHECK: 'format:check',
|
|
@@ -137,6 +141,10 @@ export const GATE_NAMES = {
|
|
|
137
141
|
LANE_HEALTH: 'lane-health',
|
|
138
142
|
/** WU-1315: Onboarding smoke test (init + wu:create validation) */
|
|
139
143
|
ONBOARDING_SMOKE_TEST: 'onboarding-smoke-test',
|
|
144
|
+
/** WU-2927: Opt-in local-prep build gate (wraps SCRIPTS.BUILD) */
|
|
145
|
+
BUILD: 'build',
|
|
146
|
+
/** WU-2927: Opt-in local-prep Playwright smoke gate */
|
|
147
|
+
E2E_SMOKE: 'e2e-smoke',
|
|
140
148
|
};
|
|
141
149
|
|
|
142
150
|
/**
|
|
@@ -159,6 +167,10 @@ export const GATE_COMMANDS = {
|
|
|
159
167
|
TIERED_TEST: 'tiered-test',
|
|
160
168
|
/** WU-1315: Triggers onboarding smoke test */
|
|
161
169
|
ONBOARDING_SMOKE_TEST: 'onboarding-smoke-test',
|
|
170
|
+
/** WU-2927: Triggers opt-in local-prep build gate */
|
|
171
|
+
BUILD: 'build-gate',
|
|
172
|
+
/** WU-2927: Triggers opt-in local-prep e2e-smoke gate */
|
|
173
|
+
E2E_SMOKE: 'e2e-smoke-gate',
|
|
162
174
|
};
|
|
163
175
|
|
|
164
176
|
/**
|
|
@@ -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
|
-
|
|
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> {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<!-- LUMENFLOW:START -->
|
|
2
|
+
|
|
1
3
|
# Universal Agent Instructions
|
|
2
4
|
|
|
3
5
|
**Last updated:** {{DATE}}
|
|
@@ -87,6 +89,44 @@ pnpm mem:checkpoint --wu WU-XXXX --note '<progress>' --next-steps '<what is next
|
|
|
87
89
|
|
|
88
90
|
**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.
|
|
89
91
|
|
|
92
|
+
### Agent-to-Agent Coordination
|
|
93
|
+
|
|
94
|
+
The shared memory signal layer now speaks the exported `A2A.V1` contract from
|
|
95
|
+
`@lumenflow/control-plane-sdk/a2a`. Local JSONL, generated Claude hooks, and
|
|
96
|
+
`mem:watch` are adapters; lumenflow.cloud uses the same contract over hosted
|
|
97
|
+
tenant/workspace transport (`workspace_id` is optional locally and required in
|
|
98
|
+
hosted buses).
|
|
99
|
+
|
|
100
|
+
Use stable identities when a role should keep receipt state across restarts:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pnpm agent:session --agent-identity codex:implementer:init-066 --wu WU-XXXX
|
|
104
|
+
pnpm mem:signal 'approve this boundary' --wu WU-XXXX --to claude:reviewer:init-066 --intent PROPOSE --requires-ack
|
|
105
|
+
pnpm mem:inbox --for codex:implementer:init-066
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Signals addressed with `--to` persist canonical `recipients[]`; legacy
|
|
109
|
+
`target_agent` is only a read-compatible single-recipient alias. Receipts are
|
|
110
|
+
per reader identity, so one agent reading a signal does not hide it from another
|
|
111
|
+
recipient. Threads and `INFO|PROPOSE|COUNTER|AGREE|REJECT` intents make
|
|
112
|
+
coordination decisions machine-readable, `requires_ack` expects a same-thread
|
|
113
|
+
`AGREE` or `REJECT`, and interrupt classes are
|
|
114
|
+
`advisory|priority|urgent` with `soon|immediate` accepted as compatibility
|
|
115
|
+
aliases.
|
|
116
|
+
|
|
117
|
+
Claude Code receives addressed `signal:received` events through generated
|
|
118
|
+
`PostToolUse` hooks. Other clients should run the daemon fallback in a side
|
|
119
|
+
terminal when they need active delivery:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pnpm mem:watch --session <session_id|display_name|agent_identity>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Before `mem:checkpoint`, `wu:prep`, or a handoff, unread directed signals are a
|
|
126
|
+
decision point. Read and ACK/REJECT them before continuing, or use
|
|
127
|
+
`pnpm wu:prep --allow-unread-signals --reason '<audit reason>'` only when the
|
|
128
|
+
override is intentional and auditable.
|
|
129
|
+
|
|
90
130
|
### Before wu:done
|
|
91
131
|
|
|
92
132
|
```bash
|
|
@@ -152,7 +192,45 @@ For detailed troubleshooting, see [troubleshooting-wu-done.md]({{DOCS_ONBOARDING
|
|
|
152
192
|
|
|
153
193
|
1. **Fit-For-Surface Verification**: Choose the least brittle verification that gives strong confidence. Prefer TDD for runtime logic when policy requires it; avoid brittle UI implementation-detail tests.
|
|
154
194
|
2. **Worktree Discipline**: After `wu:claim`, work ONLY in the worktree
|
|
155
|
-
3. **Gates Before Done**: Run `pnpm gates` before `wu:done
|
|
195
|
+
3. **Gates Before Done**: Run `pnpm gates` before `wu:done`. Per-gate skip
|
|
196
|
+
(`--skip-gate <name>`, repeatable) is the preferred bypass surface as of
|
|
197
|
+
WU-2925; legacy `--skip-gates` is deprecated for one minor cycle. Only gates
|
|
198
|
+
marked `skippable: true` (allow-list: `migration-verify`, `lane-health`,
|
|
199
|
+
`tdd-diff-evidence`, plus the WU-2927 opt-in local-prep gates `build`,
|
|
200
|
+
`integration-test`, `e2e-smoke`) or overridden via
|
|
201
|
+
`software_delivery.gates.overrides.<gate_id>.skippable=true` may be skipped.
|
|
202
|
+
Both flags require `--reason` and `--fix-wu`.
|
|
203
|
+
|
|
204
|
+
**Safety-critical gates (NEVER skippable, no override):** `format`, `lint`,
|
|
205
|
+
`typecheck`, `co-change`, `spec:linter`, `claim-validation`,
|
|
206
|
+
`unread-directed-signal`, `invariants`, `safety-critical-test`. To narrow
|
|
207
|
+
their reach without flipping the default, set
|
|
208
|
+
`software_delivery.gates.overrides.<gate_id>.applicability_paths` to a
|
|
209
|
+
glob list — never flip `skippable` on these.
|
|
210
|
+
|
|
211
|
+
**`GateResult` state legend (WU-2926).** Each gate produces one of six
|
|
212
|
+
discriminated `GateResult` states with stable glyphs:
|
|
213
|
+
- `passed` ✅ — gate ran successfully
|
|
214
|
+
- `failed` ❌ — gate ran and failed (or applicable + missing + skippable + `'fail'`)
|
|
215
|
+
- `skipped-by-agent` ⏭ — explicit `--skip-gate <name>` (audit `source: 'agent'`)
|
|
216
|
+
- `skipped-auto-not-applicable` ⊘ — gate doesn't apply to this change set
|
|
217
|
+
- `skipped-auto-missing-prereq` ⊘ — applicable + missing prereq + skippable + auto-skip
|
|
218
|
+
- `blocked-missing-prereq` 🚫 — applicable + missing prereq + `skippable: false`
|
|
219
|
+
(silent-bypass guard; exits non-zero, cannot be `--skip-gate`'d). Override
|
|
220
|
+
per-repo via `software_delivery.gates.overrides.<gate_id>.skippable=true`
|
|
221
|
+
only when the missing prerequisite is genuinely environmental.
|
|
222
|
+
|
|
223
|
+
Auto-skip + blocked states write audit NDJSON with the discriminated
|
|
224
|
+
`source` field; CFR only counts `source: 'agent'` rows. Public reference:
|
|
225
|
+
[Gates Reference](https://lumenflow.dev/reference/gates).
|
|
226
|
+
|
|
227
|
+
**Local-prep profile (WU-2927).** The opt-in
|
|
228
|
+
`software_delivery.gates.local_prep` profile extends `wu:prep` with
|
|
229
|
+
`build`, `integration-test`, and `e2e-smoke` gates that previously only ran
|
|
230
|
+
in CI. All three are `skippable: true` and on the per-gate skip allow-list.
|
|
231
|
+
See [LUMENFLOW.md gates section](LUMENFLOW.md#extended-local-prep-profile-wu-2927)
|
|
232
|
+
for the schema and latency budget.
|
|
233
|
+
|
|
156
234
|
4. **Never Bypass Hooks**: No `--no-verify`
|
|
157
235
|
5. **Vendor-Agnostic Dirty-Main Guard**: `wu:prep` and `wu:done` hard-block when main has non-allowlisted dirty files during worktree WUs (including MCP/tool-originated writes). `branch-pr` mode is exempt.
|
|
158
236
|
6. **Docs Parity For Behavior Changes**: If you change LumenFlow behavior or workflow guidance, update internal docs, Starlight docs, or both as appropriate. Generated reference docs do not cover narrative behavior changes by themselves.
|
|
@@ -204,14 +282,24 @@ LumenFlow enforces safety at the repository level via git wrappers and hooks. Fo
|
|
|
204
282
|
|
|
205
283
|
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
284
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
285
|
+
Agent plugins are a discovery and invocation on-ramp, not a replacement for repo-level LumenFlow
|
|
286
|
+
integration. **Plugin packaging is scoped under INIT-065 and not yet shipped as of 5.4.0** — the
|
|
287
|
+
guidance below applies once the packaging WUs land. If a plugin is installed alongside standalone
|
|
288
|
+
projections, use the surface-specific name: standalone skills keep local names such as
|
|
289
|
+
`design-first`, Claude plugin skills use names such as `/lumenflow:design-first`, and Codex plugin
|
|
290
|
+
use should select the installed `lumenflow` plugin or bundled skill through Codex's `@` plugin
|
|
291
|
+
selection surface. Plugin installation must not delete `.claude/skills/` or `.agents/skills/`, and
|
|
292
|
+
governed repo enforcement still requires `npx lumenflow init`, `pnpm lumenflow:integrate`, or
|
|
293
|
+
`pnpm lumenflow:integrate --sync`.
|
|
294
|
+
|
|
295
|
+
| Vendor | Skill / rules surface | Invocation |
|
|
296
|
+
| ------------ | -------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
297
|
+
| Claude Code | `.claude/skills/` + `.claude/CLAUDE.md` | `Skill` tool call, or `/skill <name>` in interactive CLI |
|
|
210
298
|
| OpenAI Codex | `AGENTS.md` + `.agents/skills/` + `.codex/agents/` | `/skills`, `$<name>` mention, implicit skills, explicit subagent usage |
|
|
211
|
-
| Cursor | `.cursor/rules/` + `.agents/skills/`
|
|
212
|
-
| Windsurf | `.windsurf/rules/` + `.agents/skills/`
|
|
213
|
-
| Aider | `CONVENTIONS.md`
|
|
214
|
-
| Cline | `.clinerules`
|
|
299
|
+
| Cursor | `.cursor/rules/` + `.agents/skills/` | `/skills` or auto-discovery |
|
|
300
|
+
| Windsurf | `.windsurf/rules/` + `.agents/skills/` | Auto-discovery; workflows via `/<workflow-name>` |
|
|
301
|
+
| Aider | `CONVENTIONS.md` | `/read CONVENTIONS.md` or `aider --read CONVENTIONS.md` |
|
|
302
|
+
| Cline | `.clinerules` | Auto-loaded |
|
|
215
303
|
|
|
216
304
|
Shared cross-vendor surfaces: `AGENTS.md` and `.agents/skills/`.
|
|
217
305
|
Vendor-specific overlays: `.claude/agents/`, `.codex/agents/`, `.cursor/rules/`, and `.windsurf/rules/`.
|
|
@@ -315,3 +403,5 @@ pnpm wu:brief --id WU-XXX --client codex-cli
|
|
|
315
403
|
|
|
316
404
|
Recovery files contain your last checkpoint, acceptance criteria, code paths, and changed files.
|
|
317
405
|
Always save checkpoints before long operations: `pnpm mem:checkpoint "progress note" --wu WU-XXX`
|
|
406
|
+
|
|
407
|
+
<!-- LUMENFLOW:END -->
|