@automagik/genie 4.260420.14 → 4.260420.15
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/dist/genie.js
CHANGED
|
@@ -3518,7 +3518,7 @@ Registering in Omni (${omniUrl})...`);let existingId=await findOmniAgent(name);i
|
|
|
3518
3518
|
text,
|
|
3519
3519
|
data,
|
|
3520
3520
|
created_at::text AS created_at
|
|
3521
|
-
`;function parseSince2(since){let match=since.match(/^(\d+)([smhd])$/);if(!match)return since;let amount=Number.parseInt(match[1],10),unit=match[2],ms={s:1000,m:60000,h:3600000,d:86400000}[unit];return new Date(Date.now()-amount*ms).toISOString()}async function queryV2Batch(filter){let sql=await getConnection(),clauses=[],values2=[],param=(v)=>{return values2.push(v),`$${values2.length}`};if(filter.afterId!=null)clauses.push(`id > ${param(filter.afterId)}`);if(filter.kindPrefix)clauses.push(`(subject LIKE ${param(
|
|
3521
|
+
`;function kindFilterToLike(input){let escaped=input.replace(/\\/g,"\\\\").replace(/%/g,"\\%").replace(/_/g,"\\_");if(escaped.includes("*"))return escaped.replace(/\*/g,"%");return`${escaped}%`}function parseSince2(since){let match=since.match(/^(\d+)([smhd])$/);if(!match)return since;let amount=Number.parseInt(match[1],10),unit=match[2],ms={s:1000,m:60000,h:3600000,d:86400000}[unit];return new Date(Date.now()-amount*ms).toISOString()}async function queryV2Batch(filter){let sql=await getConnection(),clauses=[],values2=[],param=(v)=>{return values2.push(v),`$${values2.length}`};if(filter.afterId!=null)clauses.push(`id > ${param(filter.afterId)}`);if(filter.kindPrefix){let pattern=kindFilterToLike(filter.kindPrefix);clauses.push(`(subject LIKE ${param(pattern)} ESCAPE '\\' OR kind LIKE ${param(pattern)} ESCAPE '\\')`)}if(filter.severity)clauses.push(`(COALESCE(severity, data->>'_severity') = ${param(filter.severity)})`);if(filter.since)clauses.push(`created_at >= ${param(parseSince2(filter.since))}::timestamptz`);let limit=filter.limit??500,where=clauses.length>0?`WHERE ${clauses.join(" AND ")}`:"",rows=await sql.unsafe(`SELECT ${V2_SELECT}
|
|
3522
3522
|
FROM genie_runtime_events
|
|
3523
3523
|
${where}
|
|
3524
3524
|
ORDER BY id ASC
|
|
@@ -3640,7 +3640,7 @@ Registering in Omni (${omniUrl})...`);let existingId=await findOmniAgent(name);i
|
|
|
3640
3640
|
(${rows.length} event${rows.length===1?"":"s"})`)}async function eventsListV2Command(options){try{let limit=options.limit?Number.parseInt(options.limit,10):50,rows=await queryV2Batch({kindPrefix:options.kind,severity:options.severity,since:options.since??"1h",limit});if(options.json)console.log(JSON.stringify(rows,null,2));else printV2EventsTable(rows)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying v2 events: ${msg}`),process.exit(1)}}async function eventsListCommand(options){if(options.v2)return eventsListV2Command(options);try{let queryOpts={type:options.type,entity:options.entity,since:options.since??"1h",errorsOnly:options.errorsOnly,limit:options.limit?Number.parseInt(options.limit,10):50};if(options.follow){let{followAuditEvents:followAuditEvents2}=await Promise.resolve().then(() => (init_audit(),exports_audit));console.log("Following audit events (Ctrl+C to stop)...");let handle=await followAuditEvents2(queryOpts,(row)=>{if(options.json)console.log(JSON.stringify(row));else{let time=formatRelativeTimestamp(row.created_at),entity=`${row.entity_type}:${row.entity_id}`.slice(0,40),event=row.event_type.padEnd(24),details=summarizeDetails(row.details).slice(0,60);console.log(`${time} ${event} ${entity} ${details}`)}}),shutdown3=()=>{handle.stop(),process.exit(0)};process.on("SIGINT",shutdown3),process.on("SIGTERM",shutdown3),await new Promise(()=>{});return}let rows=await queryAuditEvents(queryOpts);if(options.json)console.log(JSON.stringify(rows,null,2));else printEventsTable(rows)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying events: ${msg}`),process.exit(1)}}var DEFAULT_HIDDEN_EVENT_TYPES=new Set(["command_success","sdk.hook.started"]);async function eventsStreamCommand(options){let{followAuditEvents:followAuditEvents2}=await Promise.resolve().then(() => (init_audit(),exports_audit)),{followRuntimeEvents:followRuntimeEvents2}=await Promise.resolve().then(() => (init_runtime_events(),exports_runtime_events)),{color:color2}=await Promise.resolve().then(() => (init_term_format(),exports_term_format)),{renderAuditEvent:renderAuditEvent2,renderRuntimeEvent:renderRuntimeEvent2,formatEventLine:formatEventLine2}=await Promise.resolve().then(() => (init_event_renderer(),exports_event_renderer)),handles2=[],clockTime=(iso)=>{return(iso instanceof Date?iso:new Date(iso)).toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})};if(!options.json){let sources=options.auditOnly?"audit":options.runtimeOnly?"runtime":"audit + runtime";console.log(color2("dim",`Streaming ${sources} events (Ctrl+C to stop)...`))}if(!options.runtimeOnly){let auditHandle=await followAuditEvents2({type:options.type,entity:options.entity,errorsOnly:options.errorsOnly},(row)=>{if(!options.all&&!options.type&&DEFAULT_HIDDEN_EVENT_TYPES.has(row.event_type))return;if(options.json){console.log(JSON.stringify({stream:"audit",...row}));return}console.log(formatEventLine2(clockTime(row.created_at),renderAuditEvent2({entity_type:row.entity_type,entity_id:row.entity_id,event_type:row.event_type,details:row.details})))});handles2.push(auditHandle)}if(!options.auditOnly){let validKinds=["user","assistant","message","state","tool_call","tool_result","system","qa"],kinds=options.kind&&validKinds.includes(options.kind)?[options.kind]:void 0,agentIds=options.agent?[options.agent]:void 0,runtimeHandle=await followRuntimeEvents2({kinds,agentIds,scopeMode:"any"},(event)=>{if(options.json){console.log(JSON.stringify({stream:"runtime",...event}));return}console.log(formatEventLine2(clockTime(event.timestamp),renderRuntimeEvent2({kind:event.kind,agent:event.agent,team:event.team,text:event.text})))},{pollIntervalMs:2000});handles2.push(runtimeHandle)}let shutdown3=async()=>{for(let h of handles2)await h.stop();process.exit(0)};process.on("SIGINT",shutdown3),process.on("SIGTERM",shutdown3),await new Promise(()=>{})}async function eventsErrorsCommand(options){try{let patterns2=await queryErrorPatterns(options.since);if(options.json)console.log(JSON.stringify(patterns2,null,2));else printErrorsTable(patterns2)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying error patterns: ${msg}`),process.exit(1)}}function resolveCostsGroupBy(options){if(options.byWish)return"wish";if(options.byModel)return"model";return"agent"}function printCostsTable(rows,groupBy){if(rows.length===0){console.log("No cost data found.");return}let headers=[groupBy==="agent"?"Agent":groupBy==="wish"?"Wish":"Model","Total Cost","Requests","Avg Cost"],data=rows.map((r)=>[r.group_key,`$${r.total_cost.toFixed(4)}`,String(r.request_count),`$${r.avg_cost.toFixed(4)}`]),widths=headers.map((h,i2)=>{let colVals=data.map((row)=>row[i2]);return Math.min(40,Math.max(h.length,...colVals.map((v)=>v.length)))});console.log(headers.map((h,i2)=>padRight(h,widths[i2])).join(" | ")),console.log(widths.map((w)=>"-".repeat(w)).join("-+-"));for(let row of data)console.log(row.map((v,i2)=>padRight(v.slice(0,widths[i2]),widths[i2])).join(" | "));let totalCost=rows.reduce((sum,r)=>sum+r.total_cost,0),totalReqs=rows.reduce((sum,r)=>sum+r.request_count,0);console.log(`
|
|
3641
3641
|
Total: $${totalCost.toFixed(4)} across ${totalReqs} requests`)}async function eventsCostsCommand(options){try{let since=options.today?"24h":options.since??"24h",groupBy=resolveCostsGroupBy(options),rows=await queryCostBreakdown(since,groupBy);if(options.json)console.log(JSON.stringify(rows,null,2));else printCostsTable(rows,groupBy),console.log(`
|
|
3642
3642
|
\u26A0 OTel costs only include genie-spawned sessions. For full server costs: npx ccusage monthly`)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying costs: ${msg}`),process.exit(1)}}function printToolsTable(rows,groupBy){if(rows.length===0){console.log("No tool usage data found.");return}let headers=[groupBy==="tool"?"Tool":"Agent","Calls","Success","Errors","Avg Duration"],data=rows.map((r)=>[r.group_key,String(r.total_calls),String(r.success_count),String(r.error_count),r.avg_duration_ms!=null?`${r.avg_duration_ms.toFixed(0)}ms`:"-"]),widths=headers.map((h,i2)=>{let colVals=data.map((row)=>row[i2]);return Math.min(40,Math.max(h.length,...colVals.map((v)=>v.length)))});console.log(headers.map((h,i2)=>padRight(h,widths[i2])).join(" | ")),console.log(widths.map((w)=>"-".repeat(w)).join("-+-"));for(let row of data)console.log(row.map((v,i2)=>padRight(v.slice(0,widths[i2]),widths[i2])).join(" | "));let totalCalls=rows.reduce((sum,r)=>sum+r.total_calls,0);console.log(`
|
|
3643
|
-
(${totalCalls} total tool calls)`)}async function eventsToolsCommand(options){try{let since=options.since??"24h",groupBy=options.byAgent?"agent":"tool",rows=await queryToolUsage(since,groupBy);if(options.json)console.log(JSON.stringify(rows,null,2));else printToolsTable(rows,groupBy)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying tool usage: ${msg}`),process.exit(1)}}async function eventsTimelineCommand(entityId,options){try{let rows=await queryTimeline(entityId);if(options.json)console.log(JSON.stringify(rows,null,2));else printEventsTable(rows)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying timeline: ${msg}`),process.exit(1)}}function printSummary(summary){console.log("Event Summary"),console.log("============="),console.log(`Total events: ${summary.total_events}`),console.log(`Agents spawned: ${summary.agents_spawned}`),console.log(`Tasks moved: ${summary.tasks_moved}`),console.log(`API requests: ${summary.api_requests}`),console.log(`Tool calls: ${summary.tool_calls}`),console.log(`Total cost: $${summary.total_cost.toFixed(4)}`),console.log(`Errors: ${summary.error_count}`)}async function eventsSummaryCommand(options){try{let since=options.today?"24h":options.since??"24h",summary=await querySummary(since);if(options.json)console.log(JSON.stringify(summary,null,2));else printSummary(summary)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying summary: ${msg}`),process.exit(1)}}async function eventsScanCommand(options){let{spawnSync:spawnSync5}=__require("child_process"),args=["ccusage","monthly"];if(options.since)args.push("--since",options.since);if(options.json)args.push("--json");if(options.breakdown)args.push("--breakdown");let result2=spawnSync5("npx",args,{stdio:options.json?"pipe":"inherit",timeout:30000,env:{...process.env,NODE_NO_WARNINGS:"1"}});if(result2.error)console.error("ccusage not available. Install with: npm install -g ccusage"),console.error("Or run directly: npx ccusage monthly"),process.exit(1);if(options.json&&result2.stdout)process.stdout.write(result2.stdout);if(result2.status!==0)process.exit(result2.status??1)}function registerEventsCommands(program2){let events=program2.command("events").description("Audit event log from PG");events.command("list",{isDefault:!0}).description("List recent audit events (add --v2 for the enriched genie_runtime_events surface)").option("--type <type>","Filter by event_type").option("--entity <entity>","Filter by entity_type or entity_id").option("--since <duration>","Time window (e.g., 1h, 30m, 2d)","1h").option("--errors-only","Show only error events").option("--limit <n>","Max rows to return","50").option("--json","Output as JSON").option("-f, --follow","Follow mode \u2014 real-time streaming (alias: genie events stream)").option("--v2","Use enriched genie_runtime_events surface with TraceId/SpanId/Severity/Duration columns").option("--kind <prefix>","Filter v2 rows by kind/subject prefix (e.g., mailbox, agent.lifecycle)").option("--severity <level>","Filter v2 rows by severity (debug|info|warn|error|fatal)").action(async(options)=>{await eventsListCommand(options)}),events.command("timeline-v2 <trace-id>").description("Render causal tree for a trace_id from genie_runtime_events (v2 enriched surface)").option("--json","Output as JSON").action(async(traceId,options)=>{await timelineCommand(traceId,options)}),events.command("stream-follow").description("Follow-stream enriched genie_runtime_events via LISTEN/NOTIFY + id-cursor (v2)").option("--follow","Continuously follow the stream",!0).option("--kind <prefix>","Filter by subject/kind prefix").option("--severity <level>","Filter by severity (debug|info|warn|error|fatal)").option("--since <duration>","Seed window (e.g., 5m, 1h)").option("--consumer-id <id>","Persistent consumer id for cursor resume").option("--json","Output as NDJSON").action(async(options)=>{await streamCommand({...options,follow:!0})}),events.command("migrate").description("Backfill legacy audit_events rows into genie_runtime_events (one-shot)").option("--audit","Migrate audit_events \u2192 genie_runtime_events with sentinel source tag").option("--dry-run","Report row deltas without writing").option("--since <duration>","Only migrate rows created within this window").option("--limit <n>","Cap the number of rows migrated per run",(v)=>Number.parseInt(v,10)).option("--json","Output summary as JSON").action(async(options)=>{await migrateCommand(options)}),events.command("stream").description("Stream audit + runtime events in real-time (tail -f style)").option("--type <type>","Filter by event_type").option("--entity <entity>","Filter by entity_type or entity_id").option("--errors-only","Show only error events").option("--kind <kind>","Filter runtime events by kind (tool_call, message, prompt, etc)").option("--agent <agent>","Filter runtime events by agent").option("--audit-only","Stream only audit_events (skip runtime)").option("--runtime-only","Stream only runtime events (skip audit)").option("--all","Show all events including noisy ones (command_success, etc)").option("--json","Output as JSON").action(async(options)=>{await eventsStreamCommand(options)}),events.command("errors").description("Show aggregated error patterns").option("--since <duration>","Time window (e.g., 1h, 24h, 7d)").option("--json","Output as JSON").action(async(options)=>{await eventsErrorsCommand(options)}),events.command("costs").description("Cost breakdown from OTel API request events").option("--today","Show costs from the last 24h").option("--since <duration>","Time window (e.g., 1h, 7d)","24h").option("--by-agent","Group by agent").option("--by-wish","Group by wish").option("--by-model","Group by model").option("--json","Output as JSON").action(async(options)=>{await eventsCostsCommand(options)}),events.command("tools").description("Tool usage analytics from OTel tool events").option("--since <duration>","Time window (e.g., 1h, 7d)","24h").option("--by-tool","Group by tool name (default)").option("--by-agent","Group by agent").option("--json","Output as JSON").action(async(options)=>{await eventsToolsCommand(options)}),events.command("timeline <entity-id>").description("Full event timeline for a task, agent, wish, or traceId").option("--json","Output as JSON").action(async(entityId,options)=>{await eventsTimelineCommand(entityId,options)}),events.command("summary").description("High-level stats: agents spawned, tasks moved, costs, errors").option("--today","Show summary for the last 24h").option("--since <duration>","Time window (e.g., 1h, 7d)","24h").option("--json","Output as JSON").action(async(options)=>{await eventsSummaryCommand(options)}),events.command("scan").description("Full server cost scan via ccusage (all CC sessions, not just genie-spawned)").option("--since <date>","Start date in YYYYMMDD format").option("--json","Output as JSON").option("--breakdown","Show per-model breakdown").action(async(options)=>{await eventsScanCommand(options)}),events.command("subscribe").description("Mint a signed subscription token for genie events stream --follow").requiredOption("--role <role>","RBAC role: events:admin|events:operator|events:subscriber|events:audit").option("--types <csv>","Comma-separated allowed event types (subset of role defaults)").option("--channels <csv>","Comma-separated allowed LISTEN channels (subset of role defaults)").option("--ttl <duration>","Token time-to-live (e.g., 30m, 1h, 24h). Defaults to 1h.").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--subscriber-id <id>","Stable id for the subscriber agent").option("--json","Output as JSON").action(async(options)=>{await subscribeCommand(options)});let admin=events.command("admin").description("Incident-response admin commands (sentinel H6 audited)");admin.command("revoke-subscriber").description("Add a subscription token to the revocation list").requiredOption("--token-id <id>","Token id from `genie events subscribe` output").option("--subscriber-id <id>","Subscriber id associated with the token").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--reason <text>","IR justification for revocation").option("--json","Output as JSON").action(async(options)=>{await revokeSubscriberCommand(options)}),admin.command("rotate-redaction-keys").description("Rotate redaction + audit HMAC keys, preserving prior versions for lookup").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--new-key <material>","Explicit key material (default: 32 bytes hex from /dev/urandom)").option("--target <scope>","redaction|audit|both (default: both)").option("--json","Output as JSON").action(async(options)=>{await rotateRedactionKeysCommand(options)}),admin.command("un-hash").description("Admin reverse-lookup for a Tier-A hash (emits audit.un_hash)").requiredOption("--namespace <ns>","Hash namespace (e.g., agent, actor, session)").requiredOption("--hashed-value <hash>","Tier-A hash tag to reverse").option("--candidates <csv>","Comma-separated candidate plaintexts to brute-force").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--reason <text>","IR justification (appears in audit.un_hash)").option("--ticket <ref>","Incident ticket reference").option("--json","Output as JSON").action(async(options)=>{await unHashCommand(options)}),admin.command("export-audit").description("Produce a signed audit-chain bundle (emits audit.export)").option("--signed","Require GENIE_AUDIT_EXPORT_SECRET for HMAC signing",!0).option("--since <duration>","Advisory time window (authoritative cursor is --since-id)").option("--since-id <n>","Authoritative id cursor to resume from").option("--limit <n>","Max rows to include").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--output <path>","Write bundle to file; omit to print to stdout").option("--reason <text>","IR justification (appears in audit.export)").option("--json","Output as JSON").action(async(options)=>{await exportAuditCommand(options)}),admin.command("verify-chain").description("Quick chain-integrity check (no export)").option("--since-id <n>","Start id","0").option("--limit <n>","Max rows to verify").option("--json","Output as JSON").action(async(options)=>{await verifyChainCommand(options)}),admin.command("list-revocations").description("List revoked token ids for a tenant").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--json","Output as JSON").action(async(options)=>{await listRevocationsCommand(options)})}init_term_format();import{execSync as execSync11}from"child_process";import{existsSync as existsSync37,mkdirSync as mkdirSync16,readFileSync as readFileSync25,writeFileSync as writeFileSync18}from"fs";import{dirname as dirname8,join as join45}from"path";var _boardService;async function getBoardService(){if(!_boardService)_boardService=await Promise.resolve().then(() => (init_board_service(),exports_board_service));return _boardService}var _taskService3;async function getTaskService3(){if(!_taskService3)_taskService3=await Promise.resolve().then(() => (init_task_service(),exports_task_service));return _taskService3}var _templateService;async function getTemplateService(){if(!_templateService)_templateService=await Promise.resolve().then(() => (init_template_service(),exports_template_service));return _templateService}async function resolveProjectId(name){let project=await(await getTaskService3()).getProjectByName(name);if(!project)throw Error(`Project not found: ${name}`);return project.id}async function resolveBoard(name,projectName){let bs=await getBoardService(),projectId;if(projectName)projectId=await resolveProjectId(projectName);let board=await bs.getBoard(name,projectId);if(!board)throw Error(`Board not found: ${name}`);return board}function printBoardTable(boards,projectMap){console.log(` ${padRight("NAME",24)} ${padRight("PROJECT",20)} ${padRight("COLUMNS",10)} CREATED`),console.log(` ${"\u2500".repeat(70)}`);for(let b2 of boards){let projName=b2.projectId?projectMap.get(b2.projectId)??b2.projectId:"-",colCount=String(b2.columns.length),created=formatDate(b2.createdAt);console.log(` ${padRight(truncate2(b2.name,22),24)} ${padRight(truncate2(projName,18),20)} ${padRight(colCount,10)} ${created}`)}console.log(`
|
|
3643
|
+
(${totalCalls} total tool calls)`)}async function eventsToolsCommand(options){try{let since=options.since??"24h",groupBy=options.byAgent?"agent":"tool",rows=await queryToolUsage(since,groupBy);if(options.json)console.log(JSON.stringify(rows,null,2));else printToolsTable(rows,groupBy)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying tool usage: ${msg}`),process.exit(1)}}async function eventsTimelineCommand(entityId,options){try{let rows=await queryTimeline(entityId);if(options.json)console.log(JSON.stringify(rows,null,2));else printEventsTable(rows)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying timeline: ${msg}`),process.exit(1)}}function printSummary(summary){console.log("Event Summary"),console.log("============="),console.log(`Total events: ${summary.total_events}`),console.log(`Agents spawned: ${summary.agents_spawned}`),console.log(`Tasks moved: ${summary.tasks_moved}`),console.log(`API requests: ${summary.api_requests}`),console.log(`Tool calls: ${summary.tool_calls}`),console.log(`Total cost: $${summary.total_cost.toFixed(4)}`),console.log(`Errors: ${summary.error_count}`)}async function eventsSummaryCommand(options){try{let since=options.today?"24h":options.since??"24h",summary=await querySummary(since);if(options.json)console.log(JSON.stringify(summary,null,2));else printSummary(summary)}catch(err){let msg=err instanceof Error?err.message:String(err);console.error(`Error querying summary: ${msg}`),process.exit(1)}}async function eventsScanCommand(options){let{spawnSync:spawnSync5}=__require("child_process"),args=["ccusage","monthly"];if(options.since)args.push("--since",options.since);if(options.json)args.push("--json");if(options.breakdown)args.push("--breakdown");let result2=spawnSync5("npx",args,{stdio:options.json?"pipe":"inherit",timeout:30000,env:{...process.env,NODE_NO_WARNINGS:"1"}});if(result2.error)console.error("ccusage not available. Install with: npm install -g ccusage"),console.error("Or run directly: npx ccusage monthly"),process.exit(1);if(options.json&&result2.stdout)process.stdout.write(result2.stdout);if(result2.status!==0)process.exit(result2.status??1)}function registerEventsCommands(program2){let events=program2.command("events").description("Audit event log from PG");events.command("list",{isDefault:!0}).description("List recent audit events (add --v2 for the enriched genie_runtime_events surface)").option("--type <type>","Filter by event_type").option("--entity <entity>","Filter by entity_type or entity_id").option("--since <duration>","Time window (e.g., 1h, 30m, 2d)","1h").option("--errors-only","Show only error events").option("--limit <n>","Max rows to return","50").option("--json","Output as JSON").option("-f, --follow","Follow mode \u2014 real-time streaming (alias: genie events stream)").option("--v2","Use enriched genie_runtime_events surface with TraceId/SpanId/Severity/Duration columns").option("--kind <prefix>","Filter v2 rows by kind/subject prefix (e.g., mailbox, agent.lifecycle)").option("--severity <level>","Filter v2 rows by severity (debug|info|warn|error|fatal)").action(async(options)=>{await eventsListCommand(options)}),events.command("timeline-v2 <trace-id>").description("Render causal tree for a trace_id from genie_runtime_events (v2 enriched surface)").option("--json","Output as JSON").action(async(traceId,options)=>{await timelineCommand(traceId,options)}),events.command("stream-follow").description("Follow-stream enriched genie_runtime_events via LISTEN/NOTIFY + id-cursor (v2)").option("--follow","Continuously follow the stream",!0).option("--kind <prefix>","Filter by subject/kind prefix (supports `*` globs, e.g. `detector.*`)").option("--severity <level>","Filter by severity (debug|info|warn|error|fatal)").option("--since <duration>","Seed window (e.g., 5m, 1h)").option("--consumer-id <id>","Persistent consumer id for cursor resume").option("--json","Output as NDJSON").action(async(options)=>{await streamCommand({...options,follow:!0})}),events.command("migrate").description("Backfill legacy audit_events rows into genie_runtime_events (one-shot)").option("--audit","Migrate audit_events \u2192 genie_runtime_events with sentinel source tag").option("--dry-run","Report row deltas without writing").option("--since <duration>","Only migrate rows created within this window").option("--limit <n>","Cap the number of rows migrated per run",(v)=>Number.parseInt(v,10)).option("--json","Output summary as JSON").action(async(options)=>{await migrateCommand(options)}),events.command("stream").description("Stream audit + runtime events in real-time (tail -f style)").option("--type <type>","Filter by event_type").option("--entity <entity>","Filter by entity_type or entity_id").option("--errors-only","Show only error events").option("--kind <kind>","Filter runtime events by kind (tool_call, message, prompt, etc)").option("--agent <agent>","Filter runtime events by agent").option("--audit-only","Stream only audit_events (skip runtime)").option("--runtime-only","Stream only runtime events (skip audit)").option("--all","Show all events including noisy ones (command_success, etc)").option("--json","Output as JSON").action(async(options)=>{await eventsStreamCommand(options)}),events.command("errors").description("Show aggregated error patterns").option("--since <duration>","Time window (e.g., 1h, 24h, 7d)").option("--json","Output as JSON").action(async(options)=>{await eventsErrorsCommand(options)}),events.command("costs").description("Cost breakdown from OTel API request events").option("--today","Show costs from the last 24h").option("--since <duration>","Time window (e.g., 1h, 7d)","24h").option("--by-agent","Group by agent").option("--by-wish","Group by wish").option("--by-model","Group by model").option("--json","Output as JSON").action(async(options)=>{await eventsCostsCommand(options)}),events.command("tools").description("Tool usage analytics from OTel tool events").option("--since <duration>","Time window (e.g., 1h, 7d)","24h").option("--by-tool","Group by tool name (default)").option("--by-agent","Group by agent").option("--json","Output as JSON").action(async(options)=>{await eventsToolsCommand(options)}),events.command("timeline <entity-id>").description("Full event timeline for a task, agent, wish, or traceId").option("--json","Output as JSON").action(async(entityId,options)=>{await eventsTimelineCommand(entityId,options)}),events.command("summary").description("High-level stats: agents spawned, tasks moved, costs, errors").option("--today","Show summary for the last 24h").option("--since <duration>","Time window (e.g., 1h, 7d)","24h").option("--json","Output as JSON").action(async(options)=>{await eventsSummaryCommand(options)}),events.command("scan").description("Full server cost scan via ccusage (all CC sessions, not just genie-spawned)").option("--since <date>","Start date in YYYYMMDD format").option("--json","Output as JSON").option("--breakdown","Show per-model breakdown").action(async(options)=>{await eventsScanCommand(options)}),events.command("subscribe").description("Mint a signed subscription token for genie events stream --follow").requiredOption("--role <role>","RBAC role: events:admin|events:operator|events:subscriber|events:audit").option("--types <csv>","Comma-separated allowed event types (subset of role defaults)").option("--channels <csv>","Comma-separated allowed LISTEN channels (subset of role defaults)").option("--ttl <duration>","Token time-to-live (e.g., 30m, 1h, 24h). Defaults to 1h.").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--subscriber-id <id>","Stable id for the subscriber agent").option("--json","Output as JSON").action(async(options)=>{await subscribeCommand(options)});let admin=events.command("admin").description("Incident-response admin commands (sentinel H6 audited)");admin.command("revoke-subscriber").description("Add a subscription token to the revocation list").requiredOption("--token-id <id>","Token id from `genie events subscribe` output").option("--subscriber-id <id>","Subscriber id associated with the token").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--reason <text>","IR justification for revocation").option("--json","Output as JSON").action(async(options)=>{await revokeSubscriberCommand(options)}),admin.command("rotate-redaction-keys").description("Rotate redaction + audit HMAC keys, preserving prior versions for lookup").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--new-key <material>","Explicit key material (default: 32 bytes hex from /dev/urandom)").option("--target <scope>","redaction|audit|both (default: both)").option("--json","Output as JSON").action(async(options)=>{await rotateRedactionKeysCommand(options)}),admin.command("un-hash").description("Admin reverse-lookup for a Tier-A hash (emits audit.un_hash)").requiredOption("--namespace <ns>","Hash namespace (e.g., agent, actor, session)").requiredOption("--hashed-value <hash>","Tier-A hash tag to reverse").option("--candidates <csv>","Comma-separated candidate plaintexts to brute-force").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--reason <text>","IR justification (appears in audit.un_hash)").option("--ticket <ref>","Incident ticket reference").option("--json","Output as JSON").action(async(options)=>{await unHashCommand(options)}),admin.command("export-audit").description("Produce a signed audit-chain bundle (emits audit.export)").option("--signed","Require GENIE_AUDIT_EXPORT_SECRET for HMAC signing",!0).option("--since <duration>","Advisory time window (authoritative cursor is --since-id)").option("--since-id <n>","Authoritative id cursor to resume from").option("--limit <n>","Max rows to include").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--output <path>","Write bundle to file; omit to print to stdout").option("--reason <text>","IR justification (appears in audit.export)").option("--json","Output as JSON").action(async(options)=>{await exportAuditCommand(options)}),admin.command("verify-chain").description("Quick chain-integrity check (no export)").option("--since-id <n>","Start id","0").option("--limit <n>","Max rows to verify").option("--json","Output as JSON").action(async(options)=>{await verifyChainCommand(options)}),admin.command("list-revocations").description("List revoked token ids for a tenant").option("--tenant <id>",'Tenant id. Defaults to "default".').option("--json","Output as JSON").action(async(options)=>{await listRevocationsCommand(options)})}init_term_format();import{execSync as execSync11}from"child_process";import{existsSync as existsSync37,mkdirSync as mkdirSync16,readFileSync as readFileSync25,writeFileSync as writeFileSync18}from"fs";import{dirname as dirname8,join as join45}from"path";var _boardService;async function getBoardService(){if(!_boardService)_boardService=await Promise.resolve().then(() => (init_board_service(),exports_board_service));return _boardService}var _taskService3;async function getTaskService3(){if(!_taskService3)_taskService3=await Promise.resolve().then(() => (init_task_service(),exports_task_service));return _taskService3}var _templateService;async function getTemplateService(){if(!_templateService)_templateService=await Promise.resolve().then(() => (init_template_service(),exports_template_service));return _templateService}async function resolveProjectId(name){let project=await(await getTaskService3()).getProjectByName(name);if(!project)throw Error(`Project not found: ${name}`);return project.id}async function resolveBoard(name,projectName){let bs=await getBoardService(),projectId;if(projectName)projectId=await resolveProjectId(projectName);let board=await bs.getBoard(name,projectId);if(!board)throw Error(`Board not found: ${name}`);return board}function printBoardTable(boards,projectMap){console.log(` ${padRight("NAME",24)} ${padRight("PROJECT",20)} ${padRight("COLUMNS",10)} CREATED`),console.log(` ${"\u2500".repeat(70)}`);for(let b2 of boards){let projName=b2.projectId?projectMap.get(b2.projectId)??b2.projectId:"-",colCount=String(b2.columns.length),created=formatDate(b2.createdAt);console.log(` ${padRight(truncate2(b2.name,22),24)} ${padRight(truncate2(projName,18),20)} ${padRight(colCount,10)} ${created}`)}console.log(`
|
|
3644
3644
|
${boards.length} board${boards.length===1?"":"s"}`)}function printColumnPipeline(columns,header){console.log(`
|
|
3645
3645
|
${header}`),console.log("\u2500".repeat(60));let sorted=[...columns].sort((a,b2)=>a.position-b2.position);for(let i2=0;i2<sorted.length;i2++){let c=sorted[i2],arrow=i2<sorted.length-1?" \u2192":"",gate=` [gate: ${c.gate}]`,action=c.action?` (action: ${c.action})`:"";console.log(` ${i2+1}. ${c.label??c.name}${gate}${action}${arrow}`)}console.log("")}function printTemplateTable(templates){console.log(` ${padRight("NAME",24)} ${padRight("COLUMNS",10)} ${padRight("BUILTIN",10)} DESCRIPTION`),console.log(` ${"\u2500".repeat(80)}`);for(let t of templates){let colCount=String(t.columns.length),builtin=t.isBuiltin?"yes":"no",desc=t.description?truncate2(t.description,30):"-";console.log(` ${padRight(truncate2(t.name,22),24)} ${padRight(colCount,10)} ${padRight(builtin,10)} ${desc}`)}console.log(`
|
|
3646
3646
|
${templates.length} template${templates.length===1?"":"s"}`)}async function handleBoardCreate(name,options){let bs=await getBoardService(),tmpl=await getTemplateService(),projectId;if(options.project)projectId=await resolveProjectId(options.project);let columns;if(options.from){let template=await tmpl.getTemplate(options.from);if(!template)throw Error(`Template not found: ${options.from}`);columns=template.columns}else if(options.columns)columns=options.columns.split(",").map((colName,i2)=>({name:colName.trim(),label:colName.trim(),gate:"human",position:i2}));let board=await bs.createBoard({name,projectId,description:options.description,columns});console.log(`Created board "${board.name}" (${board.id}) with ${board.columns.length} columns`)}async function handleBoardList(options){let bs=await getBoardService(),ts3=await getTaskService3(),projectId;if(options.project)projectId=await resolveProjectId(options.project);let boards=await bs.listBoards(projectId,options.all);if(options.json){console.log(JSON.stringify(boards,null,2));return}let projects=await ts3.listProjects(),projectMap=new Map;for(let p of projects)projectMap.set(p.id,p.name);printBoardTable(boards,projectMap)}async function handleBoardShow(name,options){let ts3=await getTaskService3(),board=await resolveBoard(name,options.project);if(options.json){console.log(JSON.stringify(board,null,2));return}let projectName="-";if(board.projectId){let proj=(await ts3.listProjects()).find((p)=>p.id===board.projectId);if(proj)projectName=proj.name}if(console.log(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genie",
|
|
3
|
-
"version": "4.260420.
|
|
3
|
+
"version": "4.260420.15",
|
|
4
4
|
"description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, turn them into wishes, execute with /work, validate with /review, and ship as one team.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Namastex Labs"
|