@sazabi/cli 0.13.10-dev.g8614e0d → 0.13.12-dev.gb24303c

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 (2) hide show
  1. package/dist/index.js +2 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7215,7 +7215,7 @@ service:
7215
7215
  traces:
7216
7216
  receivers: [otlp]
7217
7217
  processors: [batch]
7218
- exporters: [otlphttp/sazabi]`}]}]},{id:"adjust-pipelines",title:"Adjust pipelines",description:"Match the receivers to the sources you have configured.",steps:[{kind:"prose",text:"The `filelog` receiver collects container logs on Kubernetes; the `otlp` receiver accepts spans from instrumented services."}]}]}});var Uz;var xz=g(()=>{Ez();Uz={id:"otel_collector",name:"OpenTelemetry Collector",searchAliases:["otel","otel collector","open telemetry collector"],capabilities:["connectionless"],auth:[],delivery:["push"],lifecycleSkipReason:"Manual agent setup is not exercised by automated lifecycle tests yet.",subtitle:"Forward logs and traces from your infrastructure to Sazabi using the OpenTelemetry Collector.",features:["Kubernetes DaemonSet","Vendor-neutral standard","Extensible via contrib","Logs and traces"],evidenceHints:["otelcol, opentelemetry-collector, or collector config YAML","Kubernetes DaemonSets or Helm values for OpenTelemetry Collector","OTLP receiver/exporter pipelines that can add a Sazabi exporter"],setupSkill:q,dashboard:{iconKey:"otel-collector",intakeSourceId:"otel-collector"}}});var Yv;var Kz=g(()=>{Yv={perStreamInstructions:!0,groups:[{id:"instrument",section:"config",title:"Instrument application",description:"Configure your application or OpenTelemetry Collector to export OTLP metrics to Sazabi.",steps:[{kind:"prose",text:"These variables work with any OpenTelemetry SDK or Collector that exports OTLP metrics."},{kind:"prose",text:"Sazabi stores each incoming metric data point as a log record, so you can search metrics alongside your logs and traces and line them up with each other."},{kind:"ordered-steps",items:["Add or enable the OpenTelemetry metrics SDK in your application, or configure the OTLP metrics exporter on your OpenTelemetry Collector.","Point the OTLP metrics exporter at the Sazabi endpoint in the next step.","Set the environment variables so the exporter sends metrics to Sazabi."]}]},{id:"environment",section:"endpoint",title:"Copy OTLP metrics environment",description:"Set these variables in the environment that runs your application or Collector.",steps:[{kind:"copyable",label:"`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`",value:"https://${context.ingestHost}/v1/metrics",copyLabel:"OTLP metrics endpoint"},{kind:"copyable",label:"`OTEL_EXPORTER_OTLP_PROTOCOL`",value:"http/protobuf",copyLabel:"OTLP protocol"}]},{id:"redeploy",section:"verify",title:"Redeploy and verify",description:"Restart the application or Collector so the OpenTelemetry exporter reads the new variables.",steps:[{kind:"prose",text:"Restart or redeploy, then generate a metric to confirm Sazabi receives it as a log record."}]}]}});var Gz;var Jz=g(()=>{Kz();Gz={id:"otel_metrics",name:"OpenTelemetry Metrics",searchAliases:["otel metrics","opentelemetry metrics","otlp metrics","metrics as logs"],capabilities:["connectionless"],auth:[],delivery:["push"],lifecycleSkipReason:"Manual OTLP metrics setup is not exercised by automated lifecycle tests yet.",subtitle:"Send OpenTelemetry metrics to Sazabi's OTLP intake and store them as searchable log records.",features:["OTLP metric export","Metrics stored as log records","Any OTEL SDK or Collector"],evidenceHints:["OTLP metric exporters (OTEL_EXPORTER_OTLP_METRICS_* env vars) without a metrics backend","OpenTelemetry metrics instrumentation routed to a generic OTLP endpoint","A desire to query metrics alongside logs and traces in one place"],setupSkill:q,dashboard:{slug:"opentelemetry-metrics",iconKey:"opentelemetry-metrics",intakeSourceId:"otel-metrics"}}});var Xv,Fv,Zv;var Bz=g(()=>{pt();Xv={kind:"multi-step",steps:[{id:"prepare",title:"Create API key",description:"Create a Plain API key with webhook permissions.",steps:[{kind:"prose",text:"In Plain, open **Settings → API keys** and create a machine user API key."},{kind:"prose",text:"Grant the key these permissions: `webhookTarget:create`, `webhookTarget:edit`, `webhookTarget:delete`, `webhookTarget:read`, and `subscriptionEventTypes:read`. Workspace read access is included with every key."},{kind:"external-link",label:"Open Plain API key settings",href:"https://app.plain.com/settings/api-keys"},{kind:"prose",text:"For a full walkthrough, see the [Plain setup guide](https://docs.sazabi.com/data/sources/connect-your-account/plain)."}]},{id:"credentials",title:"Enter API key",description:"Enter the API key so Sazabi can validate workspace access.",steps:[{id:"apiKey",kind:"secret",label:"Plain API key",description:"Machine user API key with webhookTarget and subscriptionEventTypes permissions.",placeholder:"plainApiKey_..."}]}],submit:{actions:[{kind:"validate",action:"validate",input:{apiKey:"$apiKey"},resultAs:"workspace"}],metadata:{connectionMode:"managed",plainApiKey:"$apiKey"},displayName:"$workspace.workspaceName",button:Ue}},Fv={groups:[{id:"open-webhooks",section:"config",title:"Open Plain webhooks",description:"Add a webhook target in the Plain dashboard.",steps:[{kind:"prose",text:"In your [Plain workspace](https://app.plain.com/settings/webhooks), go to **Settings > Webhooks** and click **Create webhook target**."},{kind:"prose",text:"You configure and own this webhook target — you choose which event types it subscribes to in Plain. Sazabi never receives a Plain API key on this path and does not create, edit, or delete the target. To have Sazabi enumerate event types and manage the webhook target for you, connect your Plain account instead."}]},{id:"endpoint",section:"endpoint",title:"Copy webhook URL",description:"Paste your Sazabi intake URL (above) into the webhook target configuration.",steps:[{kind:"copyable",label:"Webhook URL",value:"https://${context.ingestHost}"},{kind:"prose",text:"Your key is embedded in the hostname, so the webhook needs no custom headers or query parameters. Enable the target and select the event types you want to forward."}]},{id:"verify",section:"verify",title:"Save and verify",description:"Confirm events arrive in Sazabi.",steps:[{kind:"prose",text:"Save the webhook target, then trigger a subscribed event in Plain (for example create or update a thread). Events appear in Sazabi within a few minutes."},{kind:"prose",text:"For a full walkthrough, see the [Plain setup guide](https://docs.sazabi.com/data/sources/endpoint/plain)."}]}]},Zv={content:{kind:"list",listAction:"list",listInput:{connectionId:"${context.connectionId}"},columns:[{field:"eventType",header:"Event type",cell:"mono"},{field:"description",header:"Description",cell:"muted"}],searchPlaceholder:"Search event types...",searchFields:["eventType","description"],dedupeByConfigField:"eventType",dedupeExpandArrayField:"eventTypes",aggregateSelection:{displayName:"Plain events",itemField:"eventType",configField:"eventTypes"},emptyState:{noMatches:"No event types found.",allConfigured:"All Plain event types already have streams configured.",noItems:"Plain returned no subscribable event types for this API key. Confirm the key has subscriptionEventTypes:read permission."},toStreamItem:{displayName:"$item.eventType",config:{eventType:"$item.eventType"}}}}});var MQ,Hz;var qz=g(()=>{Bz();MQ=["plainApiKey"],Hz={id:"plain",name:"Plain",searchAliases:["plain.com","plain support","plain customer support"],capabilities:["connectionless","managed"],auth:["apiToken"],delivery:["push"],lifecycleEligible:!1,lifecycleSkipReason:"No automated integration fixture yet: Plain has no sandbox workspace API for minting disposable API keys and webhook targets in CI.",sensitiveFields:MQ,subtitle:"Stream Plain customer support events into Sazabi for unified observability of your support workflows.",features:["Webhook event streaming","Multi-event webhook targets","Thread and customer activity"],evidenceHints:["@team-plain/typescript-sdk usage or PLAIN_API_KEY environment variables","core-api.uk.plain.com GraphQL calls or Plain webhook handlers","README/docs naming Plain for customer support, tickets, or threads"],setupSkill:q,dashboard:{iconKey:"plain",intakeSourceId:"plain",streamSelectorLayout:"sidepanel",streamTableColumns:[{kind:"config-text",header:"Event types",width:"w-96",configField:"eventTypes",fallbackLabel:"Unknown events"}],actions:{submit:{validate:{kind:"source-action",actionId:"validate",sensitiveInputFields:["apiKey"]}},list:{list:{kind:"source-action",actionId:"list-event-types",itemsField:"eventTypes"}}}}}});var Qv;var Wz=g(()=>{Qv={steps:[{kind:"prose",text:"Porter does not provide a generic log drain. Send OTLP telemetry to Sazabi directly from your app, or from a collector running in Porter."},{kind:"external-link",label:"Open Porter dashboard",href:"https://dashboard.porter.run"},{kind:"ordered-steps",items:["Add the environment variables below to the Porter service you want to monitor. You can also put shared values in a Porter environment group.","For Node.js apps, add an `instrumentation.cjs` (below) and load it from your start command with `NODE_OPTIONS='--require ./instrumentation.cjs' <start command>`. For other runtimes, initialize OpenTelemetry before the app handles requests, or run an OpenTelemetry Collector, Vector, or Fluent Bit service in Porter.","Redeploy the Porter service, then generate a request or test log line.","Return to Sazabi and check for incoming logs or traces. If nothing appears, check the Porter logs for OpenTelemetry exporter errors."]},{kind:"code",label:"Porter environment variables",description:"Porter injects the `PORTER_*` values from its app and deployment metadata at runtime. The keyed endpoint URL embeds your project key, so no auth header is needed.",language:"bash",value:`OTEL_EXPORTER_OTLP_ENDPOINT=https://\${context.ingestHost}
7218
+ exporters: [otlphttp/sazabi]`}]}]},{id:"adjust-pipelines",title:"Adjust pipelines",description:"Match the receivers to the sources you have configured.",steps:[{kind:"prose",text:"The `filelog` receiver collects container logs on Kubernetes; the `otlp` receiver accepts spans from instrumented services."}]}]}});var Uz;var xz=g(()=>{Ez();Uz={id:"otel_collector",name:"OpenTelemetry Collector",searchAliases:["otel","otel collector","open telemetry collector"],capabilities:["connectionless"],auth:[],delivery:["push"],lifecycleSkipReason:"Manual agent setup is not exercised by automated lifecycle tests yet.",subtitle:"Forward logs and traces from your infrastructure to Sazabi using the OpenTelemetry Collector.",features:["Kubernetes DaemonSet","Vendor-neutral standard","Extensible via contrib","Logs and traces"],evidenceHints:["otelcol, opentelemetry-collector, or collector config YAML","Kubernetes DaemonSets or Helm values for OpenTelemetry Collector","OTLP receiver/exporter pipelines that can add a Sazabi exporter"],setupSkill:q,dashboard:{iconKey:"otel-collector",intakeSourceId:"otel-collector"}}});var Yv;var Kz=g(()=>{Yv={perStreamInstructions:!0,groups:[{id:"instrument",section:"config",title:"Instrument application",description:"Configure your application or OpenTelemetry Collector to export OTLP metrics to Sazabi.",steps:[{kind:"prose",text:"These variables work with any OpenTelemetry SDK or Collector that exports OTLP metrics."},{kind:"prose",text:"Sazabi stores each incoming metric data point as a log record, so you can search metrics alongside your logs and traces and line them up with each other."},{kind:"ordered-steps",items:["Add or enable the OpenTelemetry metrics SDK in your application, or configure the OTLP metrics exporter on your OpenTelemetry Collector.","Point the OTLP metrics exporter at the Sazabi endpoint in the next step.","Set the environment variables so the exporter sends metrics to Sazabi."]}]},{id:"environment",section:"endpoint",title:"Copy OTLP metrics environment",description:"Set these variables in the environment that runs your application or Collector.",steps:[{kind:"copyable",label:"`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`",value:"https://${context.ingestHost}/v1/metrics",copyLabel:"OTLP metrics endpoint"},{kind:"copyable",label:"`OTEL_EXPORTER_OTLP_PROTOCOL`",value:"http/protobuf",copyLabel:"OTLP protocol"}]},{id:"redeploy",section:"verify",title:"Redeploy and verify",description:"Restart the application or Collector so the OpenTelemetry exporter reads the new variables.",steps:[{kind:"prose",text:"Restart or redeploy, then generate a metric to confirm Sazabi receives it as a log record."}]}]}});var Gz;var Jz=g(()=>{Kz();Gz={id:"otel_metrics",name:"OpenTelemetry Metrics",searchAliases:["otel metrics","opentelemetry metrics","otlp metrics","metrics as logs"],capabilities:["connectionless"],auth:[],delivery:["push"],lifecycleSkipReason:"Manual OTLP metrics setup is not exercised by automated lifecycle tests yet.",subtitle:"Send OpenTelemetry metrics to Sazabi's OTLP intake and store them as searchable log records.",features:["OTLP metric export","Metrics stored as log records","Any OTEL SDK or Collector"],evidenceHints:["OTLP metric exporters (OTEL_EXPORTER_OTLP_METRICS_* env vars) without a metrics backend","OpenTelemetry metrics instrumentation routed to a generic OTLP endpoint","A desire to query metrics alongside logs and traces in one place"],setupSkill:q,dashboard:{slug:"opentelemetry-metrics",iconKey:"opentelemetry-metrics",intakeSourceId:"otel-metrics"}}});var Xv,Fv,Zv;var Bz=g(()=>{pt();Xv={kind:"multi-step",steps:[{id:"prepare",title:"Create API key",description:"Create a Plain API key with webhook permissions.",steps:[{kind:"prose",text:"In Plain, open **Settings → API keys** and create a machine user API key."},{kind:"prose",text:"Grant the key these permissions: `webhookTarget:create`, `webhookTarget:edit`, `webhookTarget:delete`, `webhookTarget:read`, and `subscriptionEventTypes:read`. Workspace read access is included with every key."},{kind:"external-link",label:"Open Plain API key settings",href:"https://app.plain.com/settings/api-keys"},{kind:"prose",text:"For a full walkthrough, see the [Plain setup guide](https://docs.sazabi.com/data/sources/connect-your-account/plain)."}]},{id:"credentials",title:"Enter API key",description:"Enter the API key so Sazabi can validate workspace access.",steps:[{id:"apiKey",kind:"secret",label:"Plain API key",description:"Machine user API key with webhookTarget and subscriptionEventTypes permissions.",placeholder:"plainApiKey_..."}]}],submit:{actions:[{kind:"validate",action:"validate",input:{apiKey:"$apiKey"},resultAs:"workspace"}],metadata:{connectionMode:"managed",plainApiKey:"$apiKey"},displayName:"$workspace.workspaceName",button:Ue}},Fv={groups:[{id:"open-webhooks",section:"config",title:"Open Plain webhooks",description:"Add a webhook target in the Plain dashboard.",steps:[{kind:"prose",text:"In your [Plain workspace](https://app.plain.com/settings/webhooks), go to **Settings > Webhooks** and click **Create webhook target**."},{kind:"prose",text:"You configure and own this webhook target — you choose which event types it subscribes to in Plain. Sazabi never receives a Plain API key on this path and does not create, edit, or delete the target. To have Sazabi enumerate event types and manage the webhook target for you, connect your Plain account instead."}]},{id:"endpoint",section:"endpoint",title:"Copy webhook URL",description:"Paste your Sazabi intake URL (above) into the webhook target configuration.",steps:[{kind:"copyable",label:"Webhook URL",value:"https://${context.ingestHost}"},{kind:"prose",text:"Your key is embedded in the hostname, so the webhook needs no custom headers or query parameters. Enable the target and select the event types you want to forward."}]},{id:"verify",section:"verify",title:"Save and verify",description:"Confirm events arrive in Sazabi.",steps:[{kind:"prose",text:"Save the webhook target, then trigger a subscribed event in Plain (for example create or update a thread). Events appear in Sazabi within a few minutes."},{kind:"prose",text:"For a full walkthrough, see the [Plain setup guide](https://docs.sazabi.com/data/sources/endpoint/plain)."}]}]},Zv={content:{kind:"list",listAction:"list",listInput:{connectionId:"${context.connectionId}"},columns:[{field:"eventType",header:"Event type",cell:"mono"},{field:"description",header:"Description",cell:"muted"}],searchPlaceholder:"Search event types...",searchFields:["eventType","description"],dedupeByConfigField:"eventType",dedupeExpandArrayField:"eventTypes",aggregateSelection:{displayName:"Plain events",itemField:"eventType",configField:"eventTypes"},emptyState:{noMatches:"No event types found.",allConfigured:"All Plain event types already have streams configured.",noItems:"Plain returned no subscribable event types for this API key. Confirm the key has subscriptionEventTypes:read permission."},toStreamItem:{displayName:"$item.eventType",config:{eventType:"$item.eventType"}}}}});var MQ,Hz;var qz=g(()=>{Bz();MQ=["plainApiKey"],Hz={id:"plain",name:"Plain",searchAliases:["plain.com","plain support","plain customer support"],capabilities:["connectionless","managed"],auth:["apiToken"],delivery:["push"],lifecycleEligible:!1,lifecycleSkipReason:"No automated integration fixture yet: Plain has no sandbox workspace API for minting disposable API keys and webhook targets in CI.",sensitiveFields:MQ,subtitle:"Stream Plain customer support events into Sazabi for unified observability of your support workflows.",features:["Webhook event streaming","Multi-event webhook targets","Thread and customer activity"],evidenceHints:["@team-plain/typescript-sdk usage or PLAIN_API_KEY environment variables","core-api.uk.plain.com GraphQL calls or Plain webhook handlers","README/docs naming Plain for customer support, tickets, or threads"],setupSkill:q,dashboard:{iconKey:"plain",intakeSourceId:"plain",streamSelectorLayout:"sidepanel",streamTableColumns:[{kind:"config-text",header:"Event types",width:"w-96",configField:"eventTypes",fallbackLabel:"Unknown events"}],actions:{submit:{validate:{kind:"source-action",actionId:"validate",sensitiveInputFields:["apiKey"]}},list:{list:{kind:"source-action",actionId:"list-event-types",itemsField:"eventTypes"}}}}}});var Qv;var Wz=g(()=>{Qv={groups:[{id:"send-telemetry",section:"config",title:"Send OpenTelemetry",description:"Export OTLP telemetry to Sazabi from your Porter app or a collector running in Porter.",steps:[{kind:"prose",text:"Porter does not provide a generic log drain. Send OTLP telemetry to Sazabi directly from your app, or from a collector running in Porter."},{kind:"external-link",label:"Open Porter dashboard",href:"https://dashboard.porter.run"},{kind:"ordered-steps",items:["Add the environment variables below to the Porter service you want to monitor. You can also put shared values in a Porter environment group.","For Node.js apps, add an `instrumentation.cjs` (below) and load it from your start command with `NODE_OPTIONS='--require ./instrumentation.cjs' <start command>`. For other runtimes, initialize OpenTelemetry before the app handles requests, or run an OpenTelemetry Collector, Vector, or Fluent Bit service in Porter.","Redeploy the Porter service, then generate a request or test log line.","Return to Sazabi and check for incoming logs or traces. If nothing appears, check the Porter logs for OpenTelemetry exporter errors."]}]},{id:"configure-exporter",section:"config",title:"Configure the exporter",description:"Set the OTLP environment variables and initialize the OpenTelemetry SDK.",steps:[{kind:"code",label:"Porter environment variables",description:"Porter injects the `PORTER_*` values from its app and deployment metadata at runtime. The keyed endpoint URL embeds your project key, so no auth header is needed.",language:"bash",value:`OTEL_EXPORTER_OTLP_ENDPOINT=https://\${context.ingestHost}
7219
7219
  OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
7220
7220
  OTEL_SERVICE_NAME=$PORTER_APP_SERVICE_NAME
7221
7221
  OTEL_RESOURCE_ATTRIBUTES=service.version=$PORTER_IMAGE_TAG,porter.revision=$PORTER_POD_REVISION,porter.pod.name=$PORTER_POD_NAME`,copyLabel:"Porter environment variables"},{kind:"code-tabs",label:"Install the OpenTelemetry SDK",description:"Install the SDK if your app does not already initialize OpenTelemetry. Node.js apps then add the `instrumentation.cjs` shown below.",tabs:[{id:"node",label:"Node.js",language:"bash",value:"bun add @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-proto @opentelemetry/exporter-logs-otlp-proto @opentelemetry/sdk-logs",copyLabel:"Node.js OpenTelemetry install"},{id:"python",label:"Python",language:"bash",value:`pip install opentelemetry-distro opentelemetry-exporter-otlp-proto-http
@@ -7249,7 +7249,7 @@ try {
7249
7249
  });
7250
7250
  } catch (err) {
7251
7251
  console.error("OpenTelemetry initialization failed", err);
7252
- }`,copyLabel:"Node.js instrumentation.cjs",collapsible:!0},{kind:"prose",text:"Load `instrumentation.cjs` from your **start command** only, for example `NODE_OPTIONS='--require ./instrumentation.cjs' node server.js`. Do not set a global `NODE_OPTIONS` environment variable: it also applies during build and install, where the relative `--require` path resolves from inside `node_modules/<pkg>/` and breaks dependency postinstall scripts. If your platform forces an env var, use an absolute path such as `--require /workspace/instrumentation.cjs`."}]}});var Mz;var Yz=g(()=>{Wz();Mz={id:"porter",name:"Porter",capabilities:["connectionless"],auth:[],delivery:["push"],lifecycleEligible:!1,lifecycleSkipReason:"Manual OTEL setup is not exercised by automated lifecycle tests yet.",subtitle:"Forward your Porter application logs and traces directly to Sazabi for real-time monitoring.",features:["Application logs","Deployment logs","Service monitoring"],evidenceHints:["porter.yaml or .github/workflows/porter.yml","PORTER_* environment variables","README/docs naming Porter (porter.run) as the deploy host"],setupSkill:q,dashboard:{iconKey:"porter",intakeSourceId:"porter"}}});var Vv,YQ,ek,tk;var Xz=g(()=>{pt();Vv={kind:"multi-step",steps:[{id:"prepare",title:"Create key",description:"Create a PostHog personal API key with the required scopes.",steps:[{kind:"prose",text:"Create a personal API key in your PostHog account under **Settings > Personal API keys** ([US](https://us.posthog.com/settings/user-api-keys) · [EU](https://eu.posthog.com/settings/user-api-keys))."},{kind:"prose",text:"Grant it these scopes:\n\n- `project:read` - list your projects\n- `organization:read` - show your organization\n- `hog_function:write` - install the webhook destination"},{kind:"prose",text:"For a full walkthrough, see the [PostHog setup guide](https://docs.sazabi.com/data/sources/connect-your-account/posthog)."}]},{id:"credentials",title:"Enter API key",description:"Enter the API key so Sazabi can validate the organization.",steps:[{id:"token",kind:"secret",label:"Personal API key",placeholder:"phx_..."}]}],submit:{actions:[{kind:"validate",action:"validate",input:{token:"$token"},resultAs:"validate"},{kind:"preflight",action:"preflight",input:{token:"$token",region:"$validate.posthogApiRegion",organizationId:"$validate.posthogOrganizationId"}}],metadata:{posthogPersonalApiKey:"$token",posthogApiRegion:"$validate.posthogApiRegion",posthogOrganizationId:"$validate.posthogOrganizationId",posthogOrganizationName:"$validate.posthogOrganizationName",connectionMode:"managed"},button:Ue}},YQ=[{field:"name",header:"Project"},{field:"organizationName",header:"Organization",width:"w-48",transform:"fallback: - "}],ek={content:{kind:"list",listAction:"list",listInput:{connectionId:"${context.connectionId}"},columns:YQ,searchPlaceholder:"Search projects...",searchFields:["name","organizationName"],dedupeByConfigField:"posthogProjectId",emptyState:{noMatches:"No projects found.",allConfigured:"All projects already have PostHog destinations configured."},toStreamItem:{displayName:"$item.name",config:{posthogProjectId:"$item.id",posthogProjectName:"$item.name"}}}},tk={groups:[{id:"prepare",section:"config",title:"Open destination form",description:"Create an HTTP Webhook destination in PostHog.",steps:[{kind:"prose",text:"Configure an [HTTP Webhook destination](https://${context.posthogRegion}.posthog.com/pipeline/new/hog-template-webhook) in PostHog under **Data Pipeline > Destinations**."},{kind:"prose",text:"Use the values in the next step and set your webhook body template to the default event and person payload."}]},{id:"values",section:"endpoint",title:"Copy destination values",description:"Paste these values into the PostHog HTTP Webhook destination form.",steps:[{kind:"copyable",label:"Destination URL",value:"https://${context.ingestHost}"},{kind:"copyable",label:"Method",value:"POST"},{kind:"code",label:"Body template",language:"json",copyLabel:"Body template",value:`{
7252
+ }`,copyLabel:"Node.js instrumentation.cjs",collapsible:!0},{kind:"prose",text:"Load `instrumentation.cjs` from your **start command** only, for example `NODE_OPTIONS='--require ./instrumentation.cjs' node server.js`. Do not set a global `NODE_OPTIONS` environment variable: it also applies during build and install, where the relative `--require` path resolves from inside `node_modules/<pkg>/` and breaks dependency postinstall scripts. If your platform forces an env var, use an absolute path such as `--require /workspace/instrumentation.cjs`."}]}]}});var Mz;var Yz=g(()=>{Wz();Mz={id:"porter",name:"Porter",capabilities:["connectionless"],auth:[],delivery:["push"],lifecycleEligible:!1,lifecycleSkipReason:"Manual OTEL setup is not exercised by automated lifecycle tests yet.",subtitle:"Forward your Porter application logs and traces directly to Sazabi for real-time monitoring.",features:["Application logs","Deployment logs","Service monitoring"],evidenceHints:["porter.yaml or .github/workflows/porter.yml","PORTER_* environment variables","README/docs naming Porter (porter.run) as the deploy host"],setupSkill:q,dashboard:{iconKey:"porter",intakeSourceId:"porter"}}});var Vv,YQ,ek,tk;var Xz=g(()=>{pt();Vv={kind:"multi-step",steps:[{id:"prepare",title:"Create key",description:"Create a PostHog personal API key with the required scopes.",steps:[{kind:"prose",text:"Create a personal API key in your PostHog account under **Settings > Personal API keys** ([US](https://us.posthog.com/settings/user-api-keys) · [EU](https://eu.posthog.com/settings/user-api-keys))."},{kind:"prose",text:"Grant it these scopes:\n\n- `project:read` - list your projects\n- `organization:read` - show your organization\n- `hog_function:write` - install the webhook destination"},{kind:"prose",text:"For a full walkthrough, see the [PostHog setup guide](https://docs.sazabi.com/data/sources/connect-your-account/posthog)."}]},{id:"credentials",title:"Enter API key",description:"Enter the API key so Sazabi can validate the organization.",steps:[{id:"token",kind:"secret",label:"Personal API key",placeholder:"phx_..."}]}],submit:{actions:[{kind:"validate",action:"validate",input:{token:"$token"},resultAs:"validate"},{kind:"preflight",action:"preflight",input:{token:"$token",region:"$validate.posthogApiRegion",organizationId:"$validate.posthogOrganizationId"}}],metadata:{posthogPersonalApiKey:"$token",posthogApiRegion:"$validate.posthogApiRegion",posthogOrganizationId:"$validate.posthogOrganizationId",posthogOrganizationName:"$validate.posthogOrganizationName",connectionMode:"managed"},button:Ue}},YQ=[{field:"name",header:"Project"},{field:"organizationName",header:"Organization",width:"w-48",transform:"fallback: - "}],ek={content:{kind:"list",listAction:"list",listInput:{connectionId:"${context.connectionId}"},columns:YQ,searchPlaceholder:"Search projects...",searchFields:["name","organizationName"],dedupeByConfigField:"posthogProjectId",emptyState:{noMatches:"No projects found.",allConfigured:"All projects already have PostHog destinations configured."},toStreamItem:{displayName:"$item.name",config:{posthogProjectId:"$item.id",posthogProjectName:"$item.name"}}}},tk={groups:[{id:"prepare",section:"config",title:"Open destination form",description:"Create an HTTP Webhook destination in PostHog.",steps:[{kind:"prose",text:"Configure an [HTTP Webhook destination](https://${context.posthogRegion}.posthog.com/pipeline/new/hog-template-webhook) in PostHog under **Data Pipeline > Destinations**."},{kind:"prose",text:"Use the values in the next step and set your webhook body template to the default event and person payload."}]},{id:"values",section:"endpoint",title:"Copy destination values",description:"Paste these values into the PostHog HTTP Webhook destination form.",steps:[{kind:"copyable",label:"Destination URL",value:"https://${context.ingestHost}"},{kind:"copyable",label:"Method",value:"POST"},{kind:"code",label:"Body template",language:"json",copyLabel:"Body template",value:`{
7253
7253
  "event": "{event}",
7254
7254
  "person": "{person}"
7255
7255
  }`}]},{id:"verify",section:"verify",title:"Save and verify",description:"Save the destination and confirm events arrive in Sazabi.",steps:[{kind:"prose",text:"Save the PostHog destination, send a test event, and check Sazabi for the incoming product event."},{kind:"prose",text:"For a full walkthrough, see the [PostHog setup guide](https://docs.sazabi.com/data/sources/endpoint/posthog)."}]}]}});var XQ,Fz;var Zz=g(()=>{Xz();XQ=["posthogPersonalApiKey"],Fz={id:"posthog",name:"PostHog",capabilities:["connectionless","managed"],auth:["apiToken"],delivery:["push"],lifecycleEligible:!0,sensitiveFields:XQ,subtitle:"Forward your PostHog events directly to Sazabi for real-time product and error observability.",features:["CDP webhook forwarding","Event property mapping","Real-time streaming"],evidenceHints:["posthog-js, posthog-node, or posthog-python packages","POSTHOG_* or NEXT_PUBLIC_POSTHOG_* environment variables","README/docs naming PostHog for product analytics, feature flags, or session replay"],setupSkill:q,dashboard:{iconKey:"posthog",intakeSourceId:"posthog",streamSelectorLayout:"sidepanel",actions:{submit:{validate:{kind:"source-action",actionId:"validate-personal-api-key",sensitiveInputFields:["token"]},preflight:{kind:"source-action",actionId:"run-preflight-checks",normalize:"preflight",sensitiveInputFields:["token"]}},list:{list:{kind:"source-action",actionId:"list-projects",itemsField:"projects"}}}}}});var nk;var Qz=g(()=>{nk={perStreamInstructions:!0,groups:[{id:"plan-proxy",section:"config",title:"Plan reverse proxy",description:"Send capture traffic to Sazabi and keep PostHog config and assets going to PostHog.",steps:[{kind:"prose",text:"Configure posthog-js to use a reverse proxy as `api_host`."},{kind:"prose",text:"Send capture paths (`/e/`, `/i/`, `/s/`) to Sazabi, and send PostHog config, flags, and assets to PostHog."},{kind:"prose",text:"Session replay is controlled by your PostHog project settings, not a `posthog.init` option."}]},{id:"target",section:"endpoint",title:"Copy capture target",description:"Use this as the upstream destination for capture-path proxy rules.",steps:[{kind:"copyable",label:"Sazabi capture target",value:"https://${context.ingestHost}",copyLabel:"URL"}]},{id:"initialize",section:"config",title:"Initialize posthog-js",description:"Point posthog-js at your reverse proxy path.",steps:[{kind:"code",label:"JavaScript",language:"javascript",copyLabel:"JavaScript",value:`import posthog from "posthog-js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sazabi/cli",
3
- "version": "0.13.10-dev.g8614e0d",
3
+ "version": "0.13.12-dev.gb24303c",
4
4
  "description": "The Sazabi CLI",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",