Researched how OKR-run companies cascade (company objective -> C-suite officers per function -> department objectives -> individual key results) and encoded that shape into how the CEO builds the org. - hire_agent gains seniority (director/lead/staff; c_suite stays reserved for the CEO's privileges) and a business-card title, so the CEO hires a CTO/CFO/CMO as directors instead of a flat pool of ICs - CEO persona + goal kickoff now direct the OKR cascade: hire 2-4 officers, hand each a department objective, let them build teams; department heads get their own doctrine (hire leads/staff, cascade key results as tasks, report up) - Migration 050 adds Finance and Sales to every org's canonical departments (backfilled for existing DBs) so a real C-suite has somewhere to hire - Org chart viewport is a fixed-height scroll region: zooming rescales the diagram inside it instead of resizing the card - Unit test drives a live three-level chain: CEO -> CTO (director) -> Engineering Manager (lead) -> staff, with rank/title persisted
85 lines
3.5 KiB
TypeScript
85 lines
3.5 KiB
TypeScript
import type { DatabaseSync } from "node:sqlite";
|
|
|
|
export interface GoalKickoffPlan {
|
|
assigneeAgentId: string;
|
|
workspaceId: string | null;
|
|
title: string;
|
|
description: string;
|
|
}
|
|
|
|
/**
|
|
* Plans the kickoff work for an active goal: the chosen owner when that agent
|
|
* is still active, otherwise the top-level active agent (the CEO), bound to
|
|
* the org's primary workspace. Returns null when the org has no eligible
|
|
* agent — creating the first agent then kicks off every untouched goal, so a
|
|
* goal never stays inert.
|
|
*/
|
|
export function resolveGoalKickoff(db: DatabaseSync, input: {
|
|
orgId: string;
|
|
goalTitle: string;
|
|
goalDescription: string;
|
|
ownerAgentId: string | null;
|
|
}): GoalKickoffPlan | null {
|
|
const assigneeAgentId = activeAgentId(db, input.orgId, input.ownerAgentId) ?? topLevelActiveAgentId(db, input.orgId);
|
|
if (!assigneeAgentId) return null;
|
|
const organization = db.prepare("select name from organizations where id = ?")
|
|
.get(input.orgId) as { name: string };
|
|
return {
|
|
assigneeAgentId,
|
|
workspaceId: primaryWorkspaceId(db, input.orgId),
|
|
title: goalKickoffTitle(input.goalTitle),
|
|
description: goalKickoffDescription(organization.name, input.goalTitle, input.goalDescription),
|
|
};
|
|
}
|
|
|
|
export function goalKickoffTitle(goalTitle: string): string {
|
|
return `Operationalize goal: ${goalTitle.trim()}`;
|
|
}
|
|
|
|
export function goalKickoffDescription(companyName: string, goalTitle: string, goalDescription: string): string {
|
|
return [
|
|
`Company: ${companyName.trim()}`,
|
|
`Goal: ${goalTitle.trim()}`,
|
|
goalDescription.trim(),
|
|
"Treat this goal as the company objective and build the organization that can deliver it: hire chief officers (hire_agent, seniority \"director\", titles like CTO/CFO/CMO/COO) for the functions the goal needs, give each officer their department objective as a task, and let them build and run their own teams. Read the bound workspace, create the first operating plan, and route decisions through approvals and messages.",
|
|
].filter((line) => line.length > 0).join("\n\n");
|
|
}
|
|
|
|
/**
|
|
* Waking an agent re-enables its heartbeat (same contract as the previous
|
|
* runtime), so a kickoff assigned to an agent hired without a provider still
|
|
* starts autonomously once a provider is configured. This also resumes the
|
|
* agent's other backlog work — waking an agent wakes all of its assignments.
|
|
*/
|
|
export function ensureAgentHeartbeat(db: DatabaseSync, orgId: string, agentId: string): void {
|
|
db.prepare(`
|
|
update agents
|
|
set heartbeat_enabled = 1,
|
|
heartbeat_interval_sec = case when heartbeat_interval_sec > 0 then heartbeat_interval_sec else 120 end
|
|
where id = ? and org_id = ?
|
|
`).run(agentId, orgId);
|
|
}
|
|
|
|
function activeAgentId(db: DatabaseSync, orgId: string, agentId: string | null): string | null {
|
|
if (!agentId) return null;
|
|
const row = db.prepare("select id from agents where id = ? and org_id = ? and lifecycle = 'active'")
|
|
.get(agentId, orgId) as { id: string } | undefined;
|
|
return row?.id ?? null;
|
|
}
|
|
|
|
function topLevelActiveAgentId(db: DatabaseSync, orgId: string): string | null {
|
|
const row = db.prepare(`
|
|
select id from agents
|
|
where org_id = ? and manager_agent_id is null and lifecycle = 'active'
|
|
order by created_at asc
|
|
limit 1
|
|
`).get(orgId) as { id: string } | undefined;
|
|
return row?.id ?? null;
|
|
}
|
|
|
|
function primaryWorkspaceId(db: DatabaseSync, orgId: string): string | null {
|
|
const row = db.prepare("select id from workspaces where org_id = ? and is_primary = 1 order by created_at asc limit 1")
|
|
.get(orgId) as { id: string } | undefined;
|
|
return row?.id ?? null;
|
|
}
|