refactor: rename cli-v2 → cli, archive legacy cli, plus broker-side grants + auto-migrate
- apps/cli/ is now the canonical CLI (was apps/cli-v2/). - apps/cli/ legacy v0 archived as branch 'legacy-cli-archive' and tag 'cli-v0-legacy-final' before deletion; git history preserves it too. - .github/workflows/release-cli.yml paths updated. - pnpm-lock.yaml regenerated. Broker-side peer-grant enforcement (spec: 2026-04-15-per-peer-capabilities): - 0020_peer-grants.sql adds peer_grants jsonb + GIN index on mesh.member. - handleSend in broker fetches recipient grant maps once per send, drops messages silently when sender lacks the required capability. - POST /cli/mesh/:slug/grants to update from CLI; broker_messages_dropped_by_grant_total metric. - CLI grant/revoke/block now mirror to broker via syncToBroker. Auto-migrate on broker startup: - apps/broker/src/migrate.ts runs drizzle migrate with pg_advisory_lock before the HTTP server binds. Exits non-zero on failure so Coolify healthcheck fails closed. - Dockerfile copies packages/db/migrations into /app/migrations. - postgres 3.4.5 added as direct broker dep. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "dev-team",
|
||||
"description": "Software development team with frontend, backend, and devops groups",
|
||||
"groups": [
|
||||
{ "name": "frontend", "roles": ["lead", "member"] },
|
||||
{ "name": "backend", "roles": ["lead", "member"] },
|
||||
{ "name": "devops", "roles": ["lead", "member"] },
|
||||
{ "name": "qa", "roles": ["lead", "member"] }
|
||||
],
|
||||
"stateKeys": {
|
||||
"sprint": "current",
|
||||
"deploy-frozen": "false",
|
||||
"pr-queue": "[]"
|
||||
},
|
||||
"suggestedRoles": ["lead", "member", "reviewer"],
|
||||
"systemPromptHint": "You are part of a dev team. Coordinate with @frontend, @backend, @devops groups. Check state keys for sprint status and deploy freezes before making changes."
|
||||
}
|
||||
35
apps/cli/src/templates/dev-team.ts
Normal file
35
apps/cli/src/templates/dev-team.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { MeshTemplate } from "./index.js";
|
||||
|
||||
export const template: MeshTemplate = {
|
||||
"name": "Dev Team",
|
||||
"description": "Software development team mesh",
|
||||
"groups": [
|
||||
{
|
||||
"name": "eng",
|
||||
"roles": [
|
||||
"lead",
|
||||
"member"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "qa",
|
||||
"roles": [
|
||||
"lead",
|
||||
"member"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stateKeys": {
|
||||
"sprint": "Current sprint name",
|
||||
"board_url": "Task board URL"
|
||||
},
|
||||
"suggestedRoles": [
|
||||
"dev",
|
||||
"qa",
|
||||
"lead",
|
||||
"devops"
|
||||
],
|
||||
"systemPromptHint": "You are part of a software development team."
|
||||
};
|
||||
|
||||
export default template;
|
||||
@@ -1,30 +1,11 @@
|
||||
import devTeam from "./dev-team.json" with { type: "json" };
|
||||
import research from "./research.json" with { type: "json" };
|
||||
import opsIncident from "./ops-incident.json" with { type: "json" };
|
||||
import simulation from "./simulation.json" with { type: "json" };
|
||||
import personal from "./personal.json" with { type: "json" };
|
||||
export interface MeshTemplate { name: string; description: string; groups: Array<{ name: string; roles: string[] }>; stateKeys: Record<string, string>; suggestedRoles: string[]; systemPromptHint: string; }
|
||||
|
||||
export interface MeshTemplate {
|
||||
name: string;
|
||||
description: string;
|
||||
groups: Array<{ name: string; roles: string[] }>;
|
||||
stateKeys: Record<string, string>;
|
||||
suggestedRoles: string[];
|
||||
systemPromptHint: string;
|
||||
}
|
||||
import { template as devTeam } from "./dev-team.js";
|
||||
import { template as research } from "./research.js";
|
||||
import { template as opsIncident } from "./ops-incident.js";
|
||||
import { template as simulation } from "./simulation.js";
|
||||
import { template as personal } from "./personal.js";
|
||||
|
||||
export const TEMPLATES: Record<string, MeshTemplate> = {
|
||||
"dev-team": devTeam,
|
||||
research,
|
||||
"ops-incident": opsIncident,
|
||||
simulation,
|
||||
personal,
|
||||
};
|
||||
|
||||
export function listTemplates(): MeshTemplate[] {
|
||||
return Object.values(TEMPLATES);
|
||||
}
|
||||
|
||||
export function getTemplate(name: string): MeshTemplate | undefined {
|
||||
return TEMPLATES[name];
|
||||
}
|
||||
export const TEMPLATES: Record<string, MeshTemplate> = { "dev-team": devTeam, research, "ops-incident": opsIncident, simulation, personal };
|
||||
export function listTemplates(): MeshTemplate[] { return Object.values(TEMPLATES); }
|
||||
export function getTemplate(name: string): MeshTemplate | undefined { return TEMPLATES[name]; }
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "ops-incident",
|
||||
"description": "Incident response team with oncall, comms, and engineering groups",
|
||||
"groups": [
|
||||
{ "name": "oncall", "roles": ["primary", "secondary"] },
|
||||
{ "name": "comms", "roles": ["lead", "scribe"] },
|
||||
{ "name": "engineering", "roles": ["lead", "responder"] }
|
||||
],
|
||||
"stateKeys": {
|
||||
"incident-status": "investigating",
|
||||
"severity": "unknown",
|
||||
"commander": "",
|
||||
"timeline": "[]"
|
||||
},
|
||||
"suggestedRoles": ["commander", "primary-oncall", "scribe", "responder"],
|
||||
"systemPromptHint": "INCIDENT MODE. Priority: now for all messages. Update incident-status state. Commander coordinates. Scribe maintains timeline. Engineering fixes."
|
||||
}
|
||||
28
apps/cli/src/templates/ops-incident.ts
Normal file
28
apps/cli/src/templates/ops-incident.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { MeshTemplate } from "./index.js";
|
||||
|
||||
export const template: MeshTemplate = {
|
||||
"name": "Ops Incident",
|
||||
"description": "Incident response mesh",
|
||||
"groups": [
|
||||
{
|
||||
"name": "oncall",
|
||||
"roles": [
|
||||
"ic",
|
||||
"observer"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stateKeys": {
|
||||
"severity": "Incident severity",
|
||||
"status": "Current status"
|
||||
},
|
||||
"suggestedRoles": [
|
||||
"ic",
|
||||
"oncall",
|
||||
"observer",
|
||||
"comms"
|
||||
],
|
||||
"systemPromptHint": "You are part of an incident response team."
|
||||
};
|
||||
|
||||
export default template;
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "personal",
|
||||
"description": "Private mesh for a single user — all sessions auto-join",
|
||||
"groups": [],
|
||||
"stateKeys": {
|
||||
"focus": "",
|
||||
"todos": "[]"
|
||||
},
|
||||
"suggestedRoles": [],
|
||||
"systemPromptHint": "Personal workspace. All your Claude Code sessions share this mesh. Use state keys to track focus and todos across sessions."
|
||||
}
|
||||
17
apps/cli/src/templates/personal.ts
Normal file
17
apps/cli/src/templates/personal.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { MeshTemplate } from "./index.js";
|
||||
|
||||
export const template: MeshTemplate = {
|
||||
"name": "Personal",
|
||||
"description": "Personal workspace mesh",
|
||||
"groups": [],
|
||||
"stateKeys": {
|
||||
"focus": "Current focus"
|
||||
},
|
||||
"suggestedRoles": [
|
||||
"assistant",
|
||||
"researcher"
|
||||
],
|
||||
"systemPromptHint": "You are a personal assistant."
|
||||
};
|
||||
|
||||
export default template;
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "research",
|
||||
"description": "Research and analysis team focused on deep investigation and knowledge sharing",
|
||||
"groups": [
|
||||
{ "name": "analysis", "roles": ["lead", "analyst"] },
|
||||
{ "name": "writing", "roles": ["lead", "writer", "reviewer"] },
|
||||
{ "name": "data", "roles": ["engineer", "analyst"] }
|
||||
],
|
||||
"stateKeys": {
|
||||
"research-topic": "",
|
||||
"phase": "exploration",
|
||||
"findings-count": "0"
|
||||
},
|
||||
"suggestedRoles": ["lead", "analyst", "writer", "reviewer"],
|
||||
"systemPromptHint": "You are part of a research team. Share findings via remember(), use recall() before starting new analysis. Coordinate phases through state keys."
|
||||
}
|
||||
27
apps/cli/src/templates/research.ts
Normal file
27
apps/cli/src/templates/research.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { MeshTemplate } from "./index.js";
|
||||
|
||||
export const template: MeshTemplate = {
|
||||
"name": "Research",
|
||||
"description": "Research and analysis mesh",
|
||||
"groups": [
|
||||
{
|
||||
"name": "analysis",
|
||||
"roles": [
|
||||
"lead",
|
||||
"analyst"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stateKeys": {
|
||||
"topic": "Research topic",
|
||||
"deadline": "Due date"
|
||||
},
|
||||
"suggestedRoles": [
|
||||
"researcher",
|
||||
"analyst",
|
||||
"reviewer"
|
||||
],
|
||||
"systemPromptHint": "You are part of a research team."
|
||||
};
|
||||
|
||||
export default template;
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "simulation",
|
||||
"description": "Load testing simulation with configurable time multiplier and user personas",
|
||||
"groups": [
|
||||
{ "name": "personas", "roles": ["admin", "user", "customer"] },
|
||||
{ "name": "observers", "roles": ["monitor", "analyst"] },
|
||||
{ "name": "control", "roles": ["orchestrator"] }
|
||||
],
|
||||
"stateKeys": {
|
||||
"clock-speed": "x1",
|
||||
"sim-status": "paused",
|
||||
"tick-count": "0",
|
||||
"scenario": ""
|
||||
},
|
||||
"suggestedRoles": ["orchestrator", "persona", "monitor"],
|
||||
"systemPromptHint": "SIMULATION MODE. Follow the clock-speed state for time multiplier. Act according to your persona role and the simulated time. Report actions to @observers."
|
||||
}
|
||||
27
apps/cli/src/templates/simulation.ts
Normal file
27
apps/cli/src/templates/simulation.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { MeshTemplate } from "./index.js";
|
||||
|
||||
export const template: MeshTemplate = {
|
||||
"name": "Simulation",
|
||||
"description": "Multi-agent simulation mesh",
|
||||
"groups": [
|
||||
{
|
||||
"name": "actors",
|
||||
"roles": [
|
||||
"agent",
|
||||
"observer"
|
||||
]
|
||||
}
|
||||
],
|
||||
"stateKeys": {
|
||||
"scenario": "Simulation scenario",
|
||||
"turn": "Current turn"
|
||||
},
|
||||
"suggestedRoles": [
|
||||
"agent",
|
||||
"observer",
|
||||
"narrator"
|
||||
],
|
||||
"systemPromptHint": "You are an agent in a simulation."
|
||||
};
|
||||
|
||||
export default template;
|
||||
Reference in New Issue
Block a user