@hoststack.dev/sdk 0.4.0 → 0.6.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/dist/index.d.cts CHANGED
@@ -81,6 +81,15 @@ interface ServiceConfig {
81
81
  dockerImage?: string | null;
82
82
  registryUsername?: string | null;
83
83
  registryPassword?: string | null;
84
+ /**
85
+ * v72.2: applied to runtime logs at query time. Reflects what the
86
+ * service is currently configured to filter; null/absent means no
87
+ * filtering. See UpdateServiceConfigInput for the write side.
88
+ */
89
+ logFilterRules?: Array<{
90
+ pattern: string;
91
+ action: 'drop' | 'downgrade';
92
+ }> | null;
84
93
  }
85
94
  /**
86
95
  * Fields that live on the `service_config` row — write via PATCH
@@ -107,6 +116,18 @@ interface UpdateServiceConfigInput {
107
116
  dockerImage?: string | null;
108
117
  registryUsername?: string | null;
109
118
  registryPassword?: string | null;
119
+ /**
120
+ * v72.2: per-service runtime-log filter rules applied at query
121
+ * time. Each rule matches the message by case-insensitive
122
+ * substring; matching rows are either dropped or have their
123
+ * stream flipped from stderr → stdout. Pass an empty array to
124
+ * clear all rules; null/omitted leaves the existing rules in
125
+ * place. Capped at 50 rules.
126
+ */
127
+ logFilterRules?: Array<{
128
+ pattern: string;
129
+ action: 'drop' | 'downgrade';
130
+ }> | null;
110
131
  }
111
132
  interface Deploy {
112
133
  id: number;
@@ -118,6 +139,36 @@ interface Deploy {
118
139
  createdAt: string;
119
140
  startedAt?: string | null;
120
141
  finishedAt?: string | null;
142
+ /**
143
+ * Wall-clock for the docker build / image-pull step only.
144
+ * Null when the deploy didn't reach the build phase (cancelled
145
+ * pre-pickup) or used a pre-built image with no measured pull.
146
+ *
147
+ * v89: preserved as a legacy alias of imageBuildMs for back-compat
148
+ * with pre-v89 SDK consumers. New callers should read imageBuildMs.
149
+ */
150
+ buildDurationMs?: number | null;
151
+ /**
152
+ * v89: docker build / image-pull step only. Null on skip-build
153
+ * redeploys (reusing an already-built image) and on cache-hit deploys
154
+ * where nothing was actually built. Pair with containerBootMs to
155
+ * tell "build is slow" apart from "boot is slow".
156
+ */
157
+ imageBuildMs?: number | null;
158
+ /**
159
+ * v89: deploying → live wall-clock (container start + health check
160
+ * + traffic switch). Null on builds that failed before container
161
+ * start. Combined with imageBuildMs this gives the same total as
162
+ * the legacy buildDurationMs + the rollout — but split.
163
+ */
164
+ containerBootMs?: number | null;
165
+ /**
166
+ * Wall-clock for the full deploy pipeline (build + container
167
+ * start + health-check + traffic switch + cleanup), computed at
168
+ * serialize time from finishedAt − startedAt. Absent for deploys
169
+ * still in-flight or that never reached `startedAt`.
170
+ */
171
+ totalDurationMs?: number;
121
172
  }
122
173
  interface TriggerDeployInput {
123
174
  clearCache?: boolean;
@@ -136,6 +187,8 @@ interface Database {
136
187
  plan?: string | null;
137
188
  region?: string | null;
138
189
  projectId: number;
190
+ diskSizeGb?: number;
191
+ memoryMb?: number;
139
192
  createdAt: string;
140
193
  updatedAt: string;
141
194
  }
@@ -149,11 +202,14 @@ interface CreateDatabaseInput {
149
202
  */
150
203
  environmentId?: number;
151
204
  version?: string;
152
- plan?: 'free' | 'starter' | 'standard' | 'pro';
205
+ plan?: 'free' | 'micro' | 'starter' | 'standard' | 'pro';
153
206
  region?: string;
154
207
  }
155
208
  interface UpdateDatabaseInput {
156
209
  name?: string;
210
+ plan?: 'free' | 'micro' | 'starter' | 'standard' | 'pro';
211
+ /** Grow the database disk in GB. Cannot shrink. */
212
+ diskSizeGb?: number;
157
213
  }
158
214
  interface DatabaseCredentials {
159
215
  host: string;
@@ -216,20 +272,24 @@ interface EnvVar {
216
272
  value: string;
217
273
  isSecret: boolean;
218
274
  }
275
+ type EnvVarTarget = 'build' | 'runtime' | 'both';
219
276
  interface CreateEnvVarInput {
220
277
  key: string;
221
278
  value: string;
279
+ target?: EnvVarTarget;
222
280
  isSecret?: boolean;
223
281
  }
224
282
  interface UpdateEnvVarInput {
225
283
  key?: string;
226
284
  value?: string;
285
+ target?: EnvVarTarget;
227
286
  isSecret?: boolean;
228
287
  }
229
288
  interface BulkSetEnvVarsInput {
230
- envVars: Array<{
289
+ vars: Array<{
231
290
  key: string;
232
291
  value: string;
292
+ target?: EnvVarTarget;
233
293
  isSecret?: boolean;
234
294
  }>;
235
295
  }
@@ -512,6 +572,81 @@ declare class EnvVarsResource {
512
572
  bulkSet(teamId: IdInput, serviceId: IdInput, data: BulkSetEnvVarsInput): Promise<void>;
513
573
  }
514
574
 
575
+ type NotificationChannelType = 'slack' | 'discord' | 'email';
576
+ /**
577
+ * Events a notification channel can subscribe to. Source of truth is
578
+ * `packages/shared/src/schemas/notification-channel.ts:NOTIFICATION_CHANNEL_EVENTS`.
579
+ */
580
+ type NotificationChannelEvent = 'deploy.started' | 'deploy.succeeded' | 'deploy.failed' | 'deploy.failed_consecutive' | 'service.created' | 'service.deleted' | 'service.suspended' | 'service.resumed' | 'service.restart_failed' | 'service.auto_suspended' | 'service.acme_cert_failed' | 'git.auth_failed';
581
+ interface NotificationChannel {
582
+ id: number;
583
+ teamId: number;
584
+ type: NotificationChannelType;
585
+ name: string;
586
+ /**
587
+ * Webhook URL (Slack/Discord) or email address. The list API masks
588
+ * the value for security — only the create/update calls round-trip
589
+ * the real URL.
590
+ */
591
+ webhookUrl: string;
592
+ active: boolean;
593
+ events: NotificationChannelEvent[];
594
+ createdAt: string;
595
+ updatedAt: string;
596
+ }
597
+ declare class NotificationsResource {
598
+ private client;
599
+ constructor(client: HostStack);
600
+ /**
601
+ * List notification channels for the team. Webhook URLs are
602
+ * server-side masked in the response so this is safe to log.
603
+ */
604
+ listChannels(teamId: IdInput): Promise<{
605
+ channels: NotificationChannel[];
606
+ }>;
607
+ /**
608
+ * Create a Slack/Discord/email notification channel.
609
+ *
610
+ * For type=email, `webhookUrl` is the recipient email address; for
611
+ * type=slack/discord it's the incoming webhook URL.
612
+ *
613
+ * `events` is the explicit subscription list — an empty array means
614
+ * "receive nothing". The platform pre-selects the critical-event
615
+ * set on the dashboard, but SDK callers must pass the list
616
+ * explicitly so behaviour is deterministic.
617
+ */
618
+ createChannel(teamId: IdInput, data: {
619
+ type: NotificationChannelType;
620
+ name: string;
621
+ webhookUrl: string;
622
+ events: NotificationChannelEvent[];
623
+ }): Promise<{
624
+ channel: NotificationChannel;
625
+ }>;
626
+ /**
627
+ * Update a channel's name / active state / event subscriptions. The
628
+ * webhook URL and type are immutable — create a new channel if
629
+ * those need to change.
630
+ */
631
+ updateChannel(teamId: IdInput, channelId: number, data: {
632
+ name?: string;
633
+ active?: boolean;
634
+ events?: NotificationChannelEvent[];
635
+ }): Promise<{
636
+ channel: NotificationChannel;
637
+ }>;
638
+ /** Delete a notification channel. */
639
+ deleteChannel(teamId: IdInput, channelId: number): Promise<void>;
640
+ /**
641
+ * Fire a test event to the channel so the user can confirm the
642
+ * webhook is wired correctly. Returns the dispatch outcome.
643
+ */
644
+ testChannel(teamId: IdInput, channelId: number): Promise<{
645
+ success: boolean;
646
+ error?: string;
647
+ }>;
648
+ }
649
+
515
650
  declare class ProjectsResource {
516
651
  private client;
517
652
  constructor(client: HostStack);
@@ -537,8 +672,13 @@ declare class ProjectsResource {
537
672
 
538
673
  interface LogEntry$1 {
539
674
  timestamp: string;
540
- level?: string | null;
541
- stream?: string | null;
675
+ /**
676
+ * Parsed log level if the message is a structured JSON envelope
677
+ * (pino numeric, `{"level":"info"}`, or `{"severity":"WARNING"}`).
678
+ * `undefined` for plain-text logs.
679
+ */
680
+ level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | null;
681
+ stream?: 'stdout' | 'stderr' | null;
542
682
  message: string;
543
683
  }
544
684
  interface StreamLogsOptions {
@@ -554,15 +694,30 @@ interface StreamLogsOptions {
554
694
 
555
695
  interface LogEntry {
556
696
  timestamp: string;
557
- level?: string | null;
558
- stream?: string | null;
697
+ /**
698
+ * Parsed structured log level (pino numeric or string envelopes).
699
+ * `undefined` for plain-text logs.
700
+ */
701
+ level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | null;
702
+ stream?: 'stdout' | 'stderr' | null;
559
703
  message: string;
560
704
  }
561
705
  declare class ServicesResource {
562
706
  private client;
563
707
  constructor(client: HostStack);
564
- /** List all services for the active team. */
565
- list(teamId: IdInput): Promise<{
708
+ /**
709
+ * List services for the active team.
710
+ *
711
+ * Optional filters narrow by project, environment, status, or type.
712
+ * The server treats unknown enum values as no match (returns empty)
713
+ * rather than 400-ing.
714
+ */
715
+ list(teamId: IdInput, filters?: {
716
+ projectId?: number | string;
717
+ environmentId?: number | string;
718
+ status?: 'active' | 'deploying' | 'suspended' | 'failed' | 'not_deployed';
719
+ type?: 'web_service' | 'private_service' | 'worker' | 'cron_job' | 'static_site';
720
+ }): Promise<{
566
721
  services: Service[];
567
722
  }>;
568
723
  /** Get a single service by ID. */
@@ -587,6 +742,27 @@ declare class ServicesResource {
587
742
  getMetrics(teamId: IdInput, serviceId: IdInput): Promise<{
588
743
  metrics: ServiceMetrics;
589
744
  }>;
745
+ /**
746
+ * Get a metrics time series for a service.
747
+ *
748
+ * `from`/`to` accept ISO-8601 timestamps. Omit both for the trailing
749
+ * hour. Server picks the resolution: raw samples ≤7d, hourly pre-
750
+ * aggregates ≤30d, daily beyond that. Up to ~500 points returned.
751
+ */
752
+ getMetricsHistory(teamId: IdInput, serviceId: IdInput, options?: {
753
+ from?: string;
754
+ to?: string;
755
+ }): Promise<{
756
+ history: Array<{
757
+ timestamp: string;
758
+ cpuPercent: number;
759
+ memoryUsedMb: number;
760
+ memoryLimitMb: number;
761
+ networkRxBytes: number;
762
+ networkTxBytes: number;
763
+ diskUsedMb: number;
764
+ }>;
765
+ }>;
590
766
  /** Get service configuration. */
591
767
  getConfig(teamId: IdInput, serviceId: IdInput): Promise<{
592
768
  config: ServiceConfig;
@@ -612,7 +788,7 @@ declare class ServicesResource {
612
788
  since?: string;
613
789
  until?: string;
614
790
  stream?: 'stdout' | 'stderr';
615
- level?: 'stdout' | 'stderr' | 'info' | 'warn' | 'error' | 'debug';
791
+ level?: 'stdout' | 'stderr' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
616
792
  search?: string;
617
793
  grep?: string;
618
794
  countOnly?: boolean;
@@ -747,6 +923,12 @@ declare class HostStack {
747
923
  readonly cron: CronResource;
748
924
  /** Manage persistent disks attached to services. */
749
925
  readonly volumes: VolumesResource;
926
+ /**
927
+ * Manage notification channels — Slack/Discord webhooks + email
928
+ * recipients with per-channel event filters. Used for deploy
929
+ * failures, restart loops, ACME failures, git auth losses, etc.
930
+ */
931
+ readonly notifications: NotificationsResource;
750
932
  constructor(options: HostStackOptions);
751
933
  /**
752
934
  * Make an authenticated request to the HostStack API.
@@ -810,4 +992,4 @@ declare function buildPaginationQuery(params?: PaginationParams): string;
810
992
  */
811
993
  declare function wrapArray<T>(items: T[], params?: PaginationParams): PaginatedResponse<T>;
812
994
 
813
- export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type Domain, type EnvVar, type Environment, HostStack, HostStackError, type HostStackOptions, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetrics, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type User, buildPaginationQuery, wrapArray };
995
+ export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type DeployListResponse, type DeployLogEntry, type Domain, type EnvVar, type Environment, HostStack, HostStackError, type HostStackOptions, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type NotificationChannel, type NotificationChannelEvent, type NotificationChannelType, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetrics, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type User, buildPaginationQuery, wrapArray };
package/dist/index.d.ts CHANGED
@@ -81,6 +81,15 @@ interface ServiceConfig {
81
81
  dockerImage?: string | null;
82
82
  registryUsername?: string | null;
83
83
  registryPassword?: string | null;
84
+ /**
85
+ * v72.2: applied to runtime logs at query time. Reflects what the
86
+ * service is currently configured to filter; null/absent means no
87
+ * filtering. See UpdateServiceConfigInput for the write side.
88
+ */
89
+ logFilterRules?: Array<{
90
+ pattern: string;
91
+ action: 'drop' | 'downgrade';
92
+ }> | null;
84
93
  }
85
94
  /**
86
95
  * Fields that live on the `service_config` row — write via PATCH
@@ -107,6 +116,18 @@ interface UpdateServiceConfigInput {
107
116
  dockerImage?: string | null;
108
117
  registryUsername?: string | null;
109
118
  registryPassword?: string | null;
119
+ /**
120
+ * v72.2: per-service runtime-log filter rules applied at query
121
+ * time. Each rule matches the message by case-insensitive
122
+ * substring; matching rows are either dropped or have their
123
+ * stream flipped from stderr → stdout. Pass an empty array to
124
+ * clear all rules; null/omitted leaves the existing rules in
125
+ * place. Capped at 50 rules.
126
+ */
127
+ logFilterRules?: Array<{
128
+ pattern: string;
129
+ action: 'drop' | 'downgrade';
130
+ }> | null;
110
131
  }
111
132
  interface Deploy {
112
133
  id: number;
@@ -118,6 +139,36 @@ interface Deploy {
118
139
  createdAt: string;
119
140
  startedAt?: string | null;
120
141
  finishedAt?: string | null;
142
+ /**
143
+ * Wall-clock for the docker build / image-pull step only.
144
+ * Null when the deploy didn't reach the build phase (cancelled
145
+ * pre-pickup) or used a pre-built image with no measured pull.
146
+ *
147
+ * v89: preserved as a legacy alias of imageBuildMs for back-compat
148
+ * with pre-v89 SDK consumers. New callers should read imageBuildMs.
149
+ */
150
+ buildDurationMs?: number | null;
151
+ /**
152
+ * v89: docker build / image-pull step only. Null on skip-build
153
+ * redeploys (reusing an already-built image) and on cache-hit deploys
154
+ * where nothing was actually built. Pair with containerBootMs to
155
+ * tell "build is slow" apart from "boot is slow".
156
+ */
157
+ imageBuildMs?: number | null;
158
+ /**
159
+ * v89: deploying → live wall-clock (container start + health check
160
+ * + traffic switch). Null on builds that failed before container
161
+ * start. Combined with imageBuildMs this gives the same total as
162
+ * the legacy buildDurationMs + the rollout — but split.
163
+ */
164
+ containerBootMs?: number | null;
165
+ /**
166
+ * Wall-clock for the full deploy pipeline (build + container
167
+ * start + health-check + traffic switch + cleanup), computed at
168
+ * serialize time from finishedAt − startedAt. Absent for deploys
169
+ * still in-flight or that never reached `startedAt`.
170
+ */
171
+ totalDurationMs?: number;
121
172
  }
122
173
  interface TriggerDeployInput {
123
174
  clearCache?: boolean;
@@ -136,6 +187,8 @@ interface Database {
136
187
  plan?: string | null;
137
188
  region?: string | null;
138
189
  projectId: number;
190
+ diskSizeGb?: number;
191
+ memoryMb?: number;
139
192
  createdAt: string;
140
193
  updatedAt: string;
141
194
  }
@@ -149,11 +202,14 @@ interface CreateDatabaseInput {
149
202
  */
150
203
  environmentId?: number;
151
204
  version?: string;
152
- plan?: 'free' | 'starter' | 'standard' | 'pro';
205
+ plan?: 'free' | 'micro' | 'starter' | 'standard' | 'pro';
153
206
  region?: string;
154
207
  }
155
208
  interface UpdateDatabaseInput {
156
209
  name?: string;
210
+ plan?: 'free' | 'micro' | 'starter' | 'standard' | 'pro';
211
+ /** Grow the database disk in GB. Cannot shrink. */
212
+ diskSizeGb?: number;
157
213
  }
158
214
  interface DatabaseCredentials {
159
215
  host: string;
@@ -216,20 +272,24 @@ interface EnvVar {
216
272
  value: string;
217
273
  isSecret: boolean;
218
274
  }
275
+ type EnvVarTarget = 'build' | 'runtime' | 'both';
219
276
  interface CreateEnvVarInput {
220
277
  key: string;
221
278
  value: string;
279
+ target?: EnvVarTarget;
222
280
  isSecret?: boolean;
223
281
  }
224
282
  interface UpdateEnvVarInput {
225
283
  key?: string;
226
284
  value?: string;
285
+ target?: EnvVarTarget;
227
286
  isSecret?: boolean;
228
287
  }
229
288
  interface BulkSetEnvVarsInput {
230
- envVars: Array<{
289
+ vars: Array<{
231
290
  key: string;
232
291
  value: string;
292
+ target?: EnvVarTarget;
233
293
  isSecret?: boolean;
234
294
  }>;
235
295
  }
@@ -512,6 +572,81 @@ declare class EnvVarsResource {
512
572
  bulkSet(teamId: IdInput, serviceId: IdInput, data: BulkSetEnvVarsInput): Promise<void>;
513
573
  }
514
574
 
575
+ type NotificationChannelType = 'slack' | 'discord' | 'email';
576
+ /**
577
+ * Events a notification channel can subscribe to. Source of truth is
578
+ * `packages/shared/src/schemas/notification-channel.ts:NOTIFICATION_CHANNEL_EVENTS`.
579
+ */
580
+ type NotificationChannelEvent = 'deploy.started' | 'deploy.succeeded' | 'deploy.failed' | 'deploy.failed_consecutive' | 'service.created' | 'service.deleted' | 'service.suspended' | 'service.resumed' | 'service.restart_failed' | 'service.auto_suspended' | 'service.acme_cert_failed' | 'git.auth_failed';
581
+ interface NotificationChannel {
582
+ id: number;
583
+ teamId: number;
584
+ type: NotificationChannelType;
585
+ name: string;
586
+ /**
587
+ * Webhook URL (Slack/Discord) or email address. The list API masks
588
+ * the value for security — only the create/update calls round-trip
589
+ * the real URL.
590
+ */
591
+ webhookUrl: string;
592
+ active: boolean;
593
+ events: NotificationChannelEvent[];
594
+ createdAt: string;
595
+ updatedAt: string;
596
+ }
597
+ declare class NotificationsResource {
598
+ private client;
599
+ constructor(client: HostStack);
600
+ /**
601
+ * List notification channels for the team. Webhook URLs are
602
+ * server-side masked in the response so this is safe to log.
603
+ */
604
+ listChannels(teamId: IdInput): Promise<{
605
+ channels: NotificationChannel[];
606
+ }>;
607
+ /**
608
+ * Create a Slack/Discord/email notification channel.
609
+ *
610
+ * For type=email, `webhookUrl` is the recipient email address; for
611
+ * type=slack/discord it's the incoming webhook URL.
612
+ *
613
+ * `events` is the explicit subscription list — an empty array means
614
+ * "receive nothing". The platform pre-selects the critical-event
615
+ * set on the dashboard, but SDK callers must pass the list
616
+ * explicitly so behaviour is deterministic.
617
+ */
618
+ createChannel(teamId: IdInput, data: {
619
+ type: NotificationChannelType;
620
+ name: string;
621
+ webhookUrl: string;
622
+ events: NotificationChannelEvent[];
623
+ }): Promise<{
624
+ channel: NotificationChannel;
625
+ }>;
626
+ /**
627
+ * Update a channel's name / active state / event subscriptions. The
628
+ * webhook URL and type are immutable — create a new channel if
629
+ * those need to change.
630
+ */
631
+ updateChannel(teamId: IdInput, channelId: number, data: {
632
+ name?: string;
633
+ active?: boolean;
634
+ events?: NotificationChannelEvent[];
635
+ }): Promise<{
636
+ channel: NotificationChannel;
637
+ }>;
638
+ /** Delete a notification channel. */
639
+ deleteChannel(teamId: IdInput, channelId: number): Promise<void>;
640
+ /**
641
+ * Fire a test event to the channel so the user can confirm the
642
+ * webhook is wired correctly. Returns the dispatch outcome.
643
+ */
644
+ testChannel(teamId: IdInput, channelId: number): Promise<{
645
+ success: boolean;
646
+ error?: string;
647
+ }>;
648
+ }
649
+
515
650
  declare class ProjectsResource {
516
651
  private client;
517
652
  constructor(client: HostStack);
@@ -537,8 +672,13 @@ declare class ProjectsResource {
537
672
 
538
673
  interface LogEntry$1 {
539
674
  timestamp: string;
540
- level?: string | null;
541
- stream?: string | null;
675
+ /**
676
+ * Parsed log level if the message is a structured JSON envelope
677
+ * (pino numeric, `{"level":"info"}`, or `{"severity":"WARNING"}`).
678
+ * `undefined` for plain-text logs.
679
+ */
680
+ level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | null;
681
+ stream?: 'stdout' | 'stderr' | null;
542
682
  message: string;
543
683
  }
544
684
  interface StreamLogsOptions {
@@ -554,15 +694,30 @@ interface StreamLogsOptions {
554
694
 
555
695
  interface LogEntry {
556
696
  timestamp: string;
557
- level?: string | null;
558
- stream?: string | null;
697
+ /**
698
+ * Parsed structured log level (pino numeric or string envelopes).
699
+ * `undefined` for plain-text logs.
700
+ */
701
+ level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | null;
702
+ stream?: 'stdout' | 'stderr' | null;
559
703
  message: string;
560
704
  }
561
705
  declare class ServicesResource {
562
706
  private client;
563
707
  constructor(client: HostStack);
564
- /** List all services for the active team. */
565
- list(teamId: IdInput): Promise<{
708
+ /**
709
+ * List services for the active team.
710
+ *
711
+ * Optional filters narrow by project, environment, status, or type.
712
+ * The server treats unknown enum values as no match (returns empty)
713
+ * rather than 400-ing.
714
+ */
715
+ list(teamId: IdInput, filters?: {
716
+ projectId?: number | string;
717
+ environmentId?: number | string;
718
+ status?: 'active' | 'deploying' | 'suspended' | 'failed' | 'not_deployed';
719
+ type?: 'web_service' | 'private_service' | 'worker' | 'cron_job' | 'static_site';
720
+ }): Promise<{
566
721
  services: Service[];
567
722
  }>;
568
723
  /** Get a single service by ID. */
@@ -587,6 +742,27 @@ declare class ServicesResource {
587
742
  getMetrics(teamId: IdInput, serviceId: IdInput): Promise<{
588
743
  metrics: ServiceMetrics;
589
744
  }>;
745
+ /**
746
+ * Get a metrics time series for a service.
747
+ *
748
+ * `from`/`to` accept ISO-8601 timestamps. Omit both for the trailing
749
+ * hour. Server picks the resolution: raw samples ≤7d, hourly pre-
750
+ * aggregates ≤30d, daily beyond that. Up to ~500 points returned.
751
+ */
752
+ getMetricsHistory(teamId: IdInput, serviceId: IdInput, options?: {
753
+ from?: string;
754
+ to?: string;
755
+ }): Promise<{
756
+ history: Array<{
757
+ timestamp: string;
758
+ cpuPercent: number;
759
+ memoryUsedMb: number;
760
+ memoryLimitMb: number;
761
+ networkRxBytes: number;
762
+ networkTxBytes: number;
763
+ diskUsedMb: number;
764
+ }>;
765
+ }>;
590
766
  /** Get service configuration. */
591
767
  getConfig(teamId: IdInput, serviceId: IdInput): Promise<{
592
768
  config: ServiceConfig;
@@ -612,7 +788,7 @@ declare class ServicesResource {
612
788
  since?: string;
613
789
  until?: string;
614
790
  stream?: 'stdout' | 'stderr';
615
- level?: 'stdout' | 'stderr' | 'info' | 'warn' | 'error' | 'debug';
791
+ level?: 'stdout' | 'stderr' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
616
792
  search?: string;
617
793
  grep?: string;
618
794
  countOnly?: boolean;
@@ -747,6 +923,12 @@ declare class HostStack {
747
923
  readonly cron: CronResource;
748
924
  /** Manage persistent disks attached to services. */
749
925
  readonly volumes: VolumesResource;
926
+ /**
927
+ * Manage notification channels — Slack/Discord webhooks + email
928
+ * recipients with per-channel event filters. Used for deploy
929
+ * failures, restart loops, ACME failures, git auth losses, etc.
930
+ */
931
+ readonly notifications: NotificationsResource;
750
932
  constructor(options: HostStackOptions);
751
933
  /**
752
934
  * Make an authenticated request to the HostStack API.
@@ -810,4 +992,4 @@ declare function buildPaginationQuery(params?: PaginationParams): string;
810
992
  */
811
993
  declare function wrapArray<T>(items: T[], params?: PaginationParams): PaginatedResponse<T>;
812
994
 
813
- export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type Domain, type EnvVar, type Environment, HostStack, HostStackError, type HostStackOptions, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetrics, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type User, buildPaginationQuery, wrapArray };
995
+ export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type DeployListResponse, type DeployLogEntry, type Domain, type EnvVar, type Environment, HostStack, HostStackError, type HostStackOptions, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type NotificationChannel, type NotificationChannelEvent, type NotificationChannelType, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetrics, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type User, buildPaginationQuery, wrapArray };