diff --git a/.gitignore b/.gitignore
index c85fe68..9487e48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,4 @@ dist-deno
/*.tgz
.idea/
.eslintcache
-
+oidc
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 949ce4c..0ee8c01 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.2.2"
+ ".": "0.3.0"
}
diff --git a/.stats.yml b/.stats.yml
index fef7016..ef1f4c6 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 51
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-a1912a634af4109683e626e337c1a1f1ddf488861bd16692f4bf3a4309477d1b.yml
-openapi_spec_hash: 10ce32db64b5ec6815d861f18415be48
-config_hash: b3559c96c301e1fcdea2d7e9aba1e5e1
+configured_endpoints: 52
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-52bc64e89c8406b774158cdb7fdb239dd4c39e6bace06b32e5224b82462f9ffe.yml
+openapi_spec_hash: 647ddb91aa6aca7034f2015071c30ce6
+config_hash: d81afc6f4fabf65fc9291db9ddd79f87
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8fc77f8..2ecd74d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 0.3.0 (2026-04-07)
+
+Full Changelog: [v0.2.2...v0.3.0](https://github.com/kernel/hypeman-ts/compare/v0.2.2...v0.3.0)
+
+### Features
+
+* Add Linux auto-standby controller and E2E coverage ([ebdbe6e](https://github.com/kernel/hypeman-ts/commit/ebdbe6ed58801ccd8e9a4324aaf7eb1e0a9abe8e))
+
+
+### Bug Fixes
+
+* **internal:** gitignore generated `oidc` dir ([c734bc1](https://github.com/kernel/hypeman-ts/commit/c734bc160d0d464b7a54b54b96d4e14a8c587c00))
+
## 0.2.2 (2026-03-28)
Full Changelog: [v0.2.1...v0.2.2](https://github.com/kernel/hypeman-ts/compare/v0.2.1...v0.2.2)
diff --git a/api.md b/api.md
index 8a2770c..7cba1f7 100644
--- a/api.md
+++ b/api.md
@@ -32,6 +32,8 @@ Methods:
Types:
+- AutoStandbyPolicy
+- AutoStandbyStatus
- Instance
- InstanceStats
- PathInfo
@@ -62,6 +64,12 @@ Methods:
- client.instances.stop(id) -> Instance
- client.instances.wait(id, { ...params }) -> WaitForStateResponse
+## AutoStandby
+
+Methods:
+
+- client.instances.autoStandby.status(id) -> AutoStandbyStatus
+
## Volumes
Methods:
diff --git a/package-lock.json b/package-lock.json
index 86020c0..2413669 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@onkernel/hypeman",
- "version": "0.2.2",
+ "version": "0.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@onkernel/hypeman",
- "version": "0.2.2",
+ "version": "0.3.0",
"license": "Apache-2.0",
"dependencies": {
"dockerode": "^4.0.10",
diff --git a/package.json b/package.json
index e9b2a7c..67ec96c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@onkernel/hypeman",
- "version": "0.2.2",
+ "version": "0.3.0",
"description": "The official TypeScript library for the Hypeman API",
"author": "Hypeman <>",
"types": "dist/index.d.ts",
diff --git a/src/client.ts b/src/client.ts
index cbf1ef6..f92b1b2 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -82,6 +82,8 @@ import {
Volumes,
} from './resources/volumes';
import {
+ AutoStandbyPolicy,
+ AutoStandbyStatus,
Instance,
InstanceCreateParams,
InstanceForkParams,
@@ -837,6 +839,8 @@ export declare namespace Hypeman {
export {
Instances as Instances,
+ type AutoStandbyPolicy as AutoStandbyPolicy,
+ type AutoStandbyStatus as AutoStandbyStatus,
type Instance as Instance,
type InstanceStats as InstanceStats,
type PathInfo as PathInfo,
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 54ef490..4713806 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -43,6 +43,8 @@ export {
} from './ingresses';
export {
Instances,
+ type AutoStandbyPolicy,
+ type AutoStandbyStatus,
type Instance,
type InstanceStats,
type PathInfo,
diff --git a/src/resources/instances/auto-standby.ts b/src/resources/instances/auto-standby.ts
new file mode 100644
index 0000000..855576e
--- /dev/null
+++ b/src/resources/instances/auto-standby.ts
@@ -0,0 +1,22 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+import * as InstancesAPI from './instances';
+import { APIPromise } from '../../core/api-promise';
+import { RequestOptions } from '../../internal/request-options';
+import { path } from '../../internal/utils/path';
+
+export class AutoStandby extends APIResource {
+ /**
+ * Get auto-standby diagnostic status
+ *
+ * @example
+ * ```ts
+ * const autoStandbyStatus =
+ * await client.instances.autoStandby.status('id');
+ * ```
+ */
+ status(id: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/instances/${id}/auto-standby/status`, options);
+ }
+}
diff --git a/src/resources/instances/index.ts b/src/resources/instances/index.ts
index 10ce3e8..620f42d 100644
--- a/src/resources/instances/index.ts
+++ b/src/resources/instances/index.ts
@@ -1,7 +1,10 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+export { AutoStandby } from './auto-standby';
export {
Instances,
+ type AutoStandbyPolicy,
+ type AutoStandbyStatus,
type Instance,
type InstanceStats,
type PathInfo,
diff --git a/src/resources/instances/instances.ts b/src/resources/instances/instances.ts
index d404bdc..2106761 100644
--- a/src/resources/instances/instances.ts
+++ b/src/resources/instances/instances.ts
@@ -2,6 +2,8 @@
import { APIResource } from '../../core/resource';
import * as Shared from '../shared';
+import * as AutoStandbyAPI from './auto-standby';
+import { AutoStandby } from './auto-standby';
import * as SnapshotScheduleAPI from './snapshot-schedule';
import { SnapshotScheduleUpdateParams } from './snapshot-schedule';
import * as SnapshotsAPI from './snapshots';
@@ -15,6 +17,7 @@ import { RequestOptions } from '../../internal/request-options';
import { path } from '../../internal/utils/path';
export class Instances extends APIResource {
+ autoStandby: AutoStandbyAPI.AutoStandby = new AutoStandbyAPI.AutoStandby(this._client);
volumes: VolumesAPI.Volumes = new VolumesAPI.Volumes(this._client);
snapshots: SnapshotsAPI.Snapshots = new SnapshotsAPI.Snapshots(this._client);
snapshotSchedule: SnapshotScheduleAPI.SnapshotSchedule = new SnapshotScheduleAPI.SnapshotSchedule(
@@ -235,6 +238,114 @@ export class Instances extends APIResource {
}
}
+/**
+ * Linux-only automatic standby policy based on active inbound TCP connections
+ * observed from the host conntrack table.
+ */
+export interface AutoStandbyPolicy {
+ /**
+ * Whether automatic standby is enabled for this instance.
+ */
+ enabled?: boolean;
+
+ /**
+ * How long the instance must have zero qualifying inbound TCP connections before
+ * Hypeman places it into standby.
+ */
+ idle_timeout?: string;
+
+ /**
+ * Optional destination TCP ports that should not keep the instance awake.
+ */
+ ignore_destination_ports?: Array;
+
+ /**
+ * Optional client CIDRs that should not keep the instance awake.
+ */
+ ignore_source_cidrs?: Array;
+}
+
+export interface AutoStandbyStatus {
+ /**
+ * Number of currently tracked qualifying inbound TCP connections.
+ */
+ active_inbound_connections: number;
+
+ /**
+ * Whether the instance has any auto-standby policy configured.
+ */
+ configured: boolean;
+
+ /**
+ * Whether the instance is currently eligible to enter standby.
+ */
+ eligible: boolean;
+
+ /**
+ * Whether the configured auto-standby policy is enabled.
+ */
+ enabled: boolean;
+
+ reason:
+ | 'unsupported_platform'
+ | 'policy_missing'
+ | 'policy_disabled'
+ | 'instance_not_running'
+ | 'network_disabled'
+ | 'missing_ip'
+ | 'has_vgpu'
+ | 'active_inbound_connections'
+ | 'idle_timeout_not_elapsed'
+ | 'observer_error'
+ | 'ready_for_standby';
+
+ status:
+ | 'unsupported'
+ | 'disabled'
+ | 'ineligible'
+ | 'active'
+ | 'idle_countdown'
+ | 'ready_for_standby'
+ | 'standby_requested'
+ | 'error';
+
+ /**
+ * Whether the current host platform supports auto-standby diagnostics.
+ */
+ supported: boolean;
+
+ /**
+ * Diagnostic identifier for the runtime tracking mode in use.
+ */
+ tracking_mode: string;
+
+ /**
+ * Remaining time before the controller attempts standby, when applicable.
+ */
+ countdown_remaining?: string | null;
+
+ /**
+ * When the controller most recently observed the instance become idle.
+ */
+ idle_since?: string | null;
+
+ /**
+ * Configured idle timeout from the auto-standby policy.
+ */
+ idle_timeout?: string | null;
+
+ /**
+ * Timestamp of the most recent qualifying inbound TCP activity the controller
+ * observed.
+ */
+ last_inbound_activity_at?: string | null;
+
+ /**
+ * When the controller expects to attempt standby next, if a countdown is active.
+ */
+ next_standby_at?: string | null;
+}
+
export interface Instance {
/**
* Auto-generated unique identifier (CUID2 format)
@@ -270,6 +381,12 @@ export interface Instance {
*/
state: 'Created' | 'Initializing' | 'Running' | 'Paused' | 'Shutdown' | 'Stopped' | 'Standby' | 'Unknown';
+ /**
+ * Linux-only automatic standby policy based on active inbound TCP connections
+ * observed from the host conntrack table.
+ */
+ auto_standby?: AutoStandbyPolicy;
+
/**
* Disk I/O rate limit (human-readable, e.g., "100MB/s")
*/
@@ -684,6 +801,12 @@ export interface InstanceCreateParams {
*/
name: string;
+ /**
+ * Linux-only automatic standby policy based on active inbound TCP connections
+ * observed from the host conntrack table.
+ */
+ auto_standby?: AutoStandbyPolicy;
+
/**
* Override image CMD (like docker run ). Omit to use image
* default.
@@ -913,6 +1036,12 @@ export namespace InstanceCreateParams {
}
export interface InstanceUpdateParams {
+ /**
+ * Linux-only automatic standby policy based on active inbound TCP connections
+ * observed from the host conntrack table.
+ */
+ auto_standby?: AutoStandbyPolicy;
+
/**
* Environment variables to update (merged with existing). Only keys referenced by
* the instance's existing credential `source.env` bindings are accepted. Use this
@@ -1018,11 +1147,14 @@ export interface InstanceWaitParams {
timeout?: string;
}
+Instances.AutoStandby = AutoStandby;
Instances.Volumes = Volumes;
Instances.Snapshots = Snapshots;
export declare namespace Instances {
export {
+ type AutoStandbyPolicy as AutoStandbyPolicy,
+ type AutoStandbyStatus as AutoStandbyStatus,
type Instance as Instance,
type InstanceStats as InstanceStats,
type PathInfo as PathInfo,
@@ -1046,6 +1178,8 @@ export declare namespace Instances {
type InstanceWaitParams as InstanceWaitParams,
};
+ export { AutoStandby as AutoStandby };
+
export {
Volumes as Volumes,
type VolumeAttachParams as VolumeAttachParams,
diff --git a/src/version.ts b/src/version.ts
index bf2543c..88f4d40 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.2.2'; // x-release-please-version
+export const VERSION = '0.3.0'; // x-release-please-version
diff --git a/tests/api-resources/instances/auto-standby.test.ts b/tests/api-resources/instances/auto-standby.test.ts
new file mode 100644
index 0000000..b732d78
--- /dev/null
+++ b/tests/api-resources/instances/auto-standby.test.ts
@@ -0,0 +1,22 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Hypeman from '@onkernel/hypeman';
+
+const client = new Hypeman({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource autoStandby', () => {
+ // Mock server tests are disabled
+ test.skip('status', async () => {
+ const responsePromise = client.instances.autoStandby.status('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+});
diff --git a/tests/api-resources/instances/instances.test.ts b/tests/api-resources/instances/instances.test.ts
index 07766c5..ccfb9e1 100644
--- a/tests/api-resources/instances/instances.test.ts
+++ b/tests/api-resources/instances/instances.test.ts
@@ -28,6 +28,12 @@ describe('resource instances', () => {
const response = await client.instances.create({
image: 'docker.io/library/alpine:latest',
name: 'my-workload-1',
+ auto_standby: {
+ enabled: true,
+ idle_timeout: '5m',
+ ignore_destination_ports: [22, 9000],
+ ignore_source_cidrs: ['10.0.0.0/8', '192.168.0.0/16'],
+ },
cmd: ['echo', 'hello'],
credentials: {
OUTBOUND_OPENAI_KEY: {