@rigkit/engine 0.0.0-canary-20260518T014918-c5bc0c2

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.
@@ -0,0 +1,52 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+
4
+ export function loadDotEnv(projectDir: string): void {
5
+ for (const path of findDotEnvFiles(projectDir)) {
6
+ loadDotEnvFile(path);
7
+ }
8
+ }
9
+
10
+ function loadDotEnvFile(path: string): void {
11
+ const content = readFileSync(path, "utf8");
12
+ for (const rawLine of content.split(/\r?\n/)) {
13
+ const line = rawLine.trim();
14
+ if (!line || line.startsWith("#")) continue;
15
+
16
+ const match = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/.exec(line);
17
+ if (!match) continue;
18
+
19
+ const [, key, rawValue] = match;
20
+ if (process.env[key] !== undefined) continue;
21
+
22
+ process.env[key] = parseEnvValue(rawValue);
23
+ }
24
+ }
25
+
26
+ function findDotEnvFiles(projectDir: string): string[] {
27
+ const files: string[] = [];
28
+ let current = projectDir;
29
+
30
+ while (true) {
31
+ const candidate = join(current, ".env");
32
+ if (existsSync(candidate)) files.unshift(candidate);
33
+
34
+ const parent = dirname(current);
35
+ if (parent === current) break;
36
+ current = parent;
37
+ }
38
+
39
+ return files;
40
+ }
41
+
42
+ function parseEnvValue(rawValue: string): string {
43
+ const trimmed = rawValue.trim();
44
+ if (
45
+ (trimmed.startsWith('"') && trimmed.endsWith('"')) ||
46
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))
47
+ ) {
48
+ return trimmed.slice(1, -1);
49
+ }
50
+
51
+ return trimmed;
52
+ }
package/src/hash.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ export function stableJson(value: unknown): string {
4
+ return JSON.stringify(sortValue(value));
5
+ }
6
+
7
+ export function hash(value: unknown): string {
8
+ return createHash("sha256").update(stableJson(value)).digest("hex");
9
+ }
10
+
11
+ function sortValue(value: unknown): unknown {
12
+ if (Array.isArray(value)) return value.map(sortValue);
13
+ if (!value || typeof value !== "object") return value;
14
+
15
+ return Object.fromEntries(
16
+ Object.entries(value as Record<string, unknown>)
17
+ .sort(([a], [b]) => a.localeCompare(b))
18
+ .map(([key, inner]) => [key, sortValue(inner)]),
19
+ );
20
+ }
21
+
@@ -0,0 +1,128 @@
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ import { hash } from "./hash.ts";
5
+ import type { ProviderStorage, ProviderStorageRecord } from "./provider/types.ts";
6
+ import type { JsonValue } from "./types.ts";
7
+
8
+ export type ProviderHostStorageOptions = {
9
+ providerId: string;
10
+ rootDir?: string;
11
+ };
12
+
13
+ export type ProviderHostStorageFactory = (options: ProviderHostStorageOptions) => ProviderStorage;
14
+
15
+ type ProviderHostStorageFile = {
16
+ providerId: string;
17
+ records: Record<string, Omit<ProviderStorageRecord, "providerId" | "key">>;
18
+ };
19
+
20
+ export function defaultProviderHostStorageDir(): string {
21
+ return process.env.RIGKIT_HOST_STORAGE_DIR ?? join(homedir(), ".rigkit", "providers");
22
+ }
23
+
24
+ export function createFileProviderHostStorage(options: ProviderHostStorageOptions): ProviderStorage {
25
+ return new FileProviderHostStorage(options.providerId, providerHostStoragePath(options));
26
+ }
27
+
28
+ function providerHostStoragePath(options: ProviderHostStorageOptions): string {
29
+ const rootDir = options.rootDir ?? defaultProviderHostStorageDir();
30
+ const slug = options.providerId.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "provider";
31
+ return join(rootDir, `${slug}-${hash(options.providerId).slice(0, 12)}.json`);
32
+ }
33
+
34
+ class FileProviderHostStorage implements ProviderStorage {
35
+ constructor(
36
+ private readonly providerId: string,
37
+ private readonly path: string,
38
+ ) {}
39
+
40
+ get<Value extends JsonValue = JsonValue>(key: string): ProviderStorageRecord<Value> | undefined {
41
+ const file = this.read();
42
+ const record = file.records[key];
43
+ return record
44
+ ? {
45
+ providerId: this.providerId,
46
+ key,
47
+ value: record.value as Value,
48
+ createdAt: record.createdAt,
49
+ updatedAt: record.updatedAt,
50
+ }
51
+ : undefined;
52
+ }
53
+
54
+ set<Value extends JsonValue = JsonValue>(key: string, value: Value): ProviderStorageRecord<Value> {
55
+ const file = this.read();
56
+ const now = new Date().toISOString();
57
+ const existing = file.records[key];
58
+ const record: ProviderStorageRecord<Value> = {
59
+ providerId: this.providerId,
60
+ key,
61
+ value,
62
+ createdAt: existing?.createdAt ?? now,
63
+ updatedAt: now,
64
+ };
65
+ file.records[key] = {
66
+ value,
67
+ createdAt: record.createdAt,
68
+ updatedAt: record.updatedAt,
69
+ };
70
+ this.write(file);
71
+ return record;
72
+ }
73
+
74
+ delete(key: string): void {
75
+ const file = this.read();
76
+ delete file.records[key];
77
+ this.write(file);
78
+ }
79
+
80
+ entries(prefix = ""): ProviderStorageRecord[] {
81
+ const file = this.read();
82
+ return Object.entries(file.records)
83
+ .filter(([key]) => key.startsWith(prefix))
84
+ .sort(([a], [b]) => a.localeCompare(b))
85
+ .map(([key, record]) => ({
86
+ providerId: this.providerId,
87
+ key,
88
+ value: record.value,
89
+ createdAt: record.createdAt,
90
+ updatedAt: record.updatedAt,
91
+ }));
92
+ }
93
+
94
+ private read(): ProviderHostStorageFile {
95
+ if (!existsSync(this.path)) {
96
+ return { providerId: this.providerId, records: {} };
97
+ }
98
+
99
+ const parsed = JSON.parse(readFileSync(this.path, "utf8")) as unknown;
100
+ if (!isHostStorageFile(parsed, this.providerId)) {
101
+ throw new Error(`Invalid Rigkit provider host storage at ${this.path}`);
102
+ }
103
+ return parsed;
104
+ }
105
+
106
+ private write(file: ProviderHostStorageFile): void {
107
+ mkdirSync(dirname(this.path), { recursive: true, mode: 0o700 });
108
+ writeFileSync(this.path, `${JSON.stringify(file, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
109
+ chmodSync(this.path, 0o600);
110
+ }
111
+ }
112
+
113
+ function isHostStorageFile(value: unknown, providerId: string): value is ProviderHostStorageFile {
114
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
115
+ const record = value as { providerId?: unknown; records?: unknown };
116
+ if (record.providerId !== providerId) return false;
117
+ if (!record.records || typeof record.records !== "object" || Array.isArray(record.records)) return false;
118
+ return Object.values(record.records).every((entry) =>
119
+ Boolean(
120
+ entry &&
121
+ typeof entry === "object" &&
122
+ !Array.isArray(entry) &&
123
+ typeof (entry as { createdAt?: unknown }).createdAt === "string" &&
124
+ typeof (entry as { updatedAt?: unknown }).updatedAt === "string" &&
125
+ "value" in entry
126
+ )
127
+ );
128
+ }
package/src/index.ts ADDED
@@ -0,0 +1,46 @@
1
+ export { createDevMachineEngine, DevMachineEngine } from "./engine.ts";
2
+ export {
3
+ EngineOperationNotFoundError,
4
+ EngineOperationValidationError,
5
+ } from "./engine.ts";
6
+ export type {
7
+ EngineOperationCli,
8
+ EngineOperationCliOption,
9
+ EngineOperationCliPosition,
10
+ EngineOperationKind,
11
+ EngineOperationSource,
12
+ EngineOperationSummary,
13
+ EngineCacheClearResult,
14
+ EngineCacheClearScope,
15
+ EngineCacheEntry,
16
+ EngineCacheList,
17
+ EngineCacheScope,
18
+ GlobalFragmentStateLocationInput,
19
+ GlobalFragmentStateLocator,
20
+ InteractionPresenter,
21
+ InteractionPresentationRequest,
22
+ } from "./engine.ts";
23
+ export { createRigkitDatabase, RIGKIT_STATE_SCHEMA_VERSION, syncRigkitDatabaseSchema } from "./db/index.ts";
24
+ export { coreSchema } from "./db/schema/index.ts";
25
+ export {
26
+ createFileProviderHostStorage,
27
+ defaultProviderHostStorageDir,
28
+ } from "./host-storage.ts";
29
+ export { createStateStore } from "./state.ts";
30
+ export { RIGKIT_ENGINE_VERSION } from "./version.ts";
31
+ export {
32
+ defineConfig,
33
+ defineProvider,
34
+ env,
35
+ isRigkitConfig,
36
+ isProviderDefinition,
37
+ isWorkflow,
38
+ isWorkflowNode,
39
+ sequence,
40
+ workflow,
41
+ } from "./authoring.ts";
42
+ export type * from "./types.ts";
43
+ export type { RigkitDatabase, RigkitDatabaseSchema, SchemaSyncResult } from "./db/index.ts";
44
+ export type { ProviderHostStorageFactory, ProviderHostStorageOptions } from "./host-storage.ts";
45
+ export type * from "./provider/types.ts";
46
+ export type * from "./state.ts";
@@ -0,0 +1,113 @@
1
+ import type {
2
+ EventHandler,
3
+ ExecOptions,
4
+ ExecResult,
5
+ JsonObject,
6
+ JsonValue,
7
+ LoadedProviderDefinition,
8
+ LocalWorkspaceRuntime,
9
+ MaybePromise,
10
+ } from "../types.ts";
11
+
12
+ export type VmHandle = {
13
+ vmId: string;
14
+ };
15
+
16
+ export type SnapshotHandle = {
17
+ snapshotId: string;
18
+ sourceVmId: string;
19
+ };
20
+
21
+ export type SshOptions = {
22
+ user?: string;
23
+ };
24
+
25
+ export type SshConnection = {
26
+ kind: "ssh";
27
+ host: string;
28
+ port?: number;
29
+ username: string;
30
+ auth: { type: "token"; token: string } | { type: "privateKey"; privateKey: string };
31
+ command: string;
32
+ };
33
+
34
+ export interface BaseDevMachineProvider {
35
+ readonly providerId: string;
36
+ createVm(): Promise<VmHandle>;
37
+ createVmFromSnapshot(input: { snapshotId: string }): Promise<VmHandle>;
38
+ exec(vm: VmHandle, command: string, options?: ExecOptions): Promise<ExecResult>;
39
+ readFile(vm: VmHandle, path: string): Promise<string>;
40
+ writeFile(vm: VmHandle, path: string, content: string): Promise<void>;
41
+ snapshot(vm: VmHandle): Promise<SnapshotHandle>;
42
+ ssh(vm: VmHandle, options?: SshOptions): Promise<SshConnection>;
43
+ deleteVm(vm: VmHandle): Promise<void>;
44
+ }
45
+
46
+ export type InteractionPresentationRequest = {
47
+ id: string;
48
+ nodePath: string;
49
+ title: string;
50
+ url: string;
51
+ instructions?: string;
52
+ };
53
+
54
+ export type InteractionPresenter = (request: InteractionPresentationRequest) => Promise<void>;
55
+
56
+ export type ProviderInteractionSession<Result = void> = {
57
+ id?: string;
58
+ title: string;
59
+ url: string;
60
+ instructions?: string;
61
+ completed: Promise<Result>;
62
+ stop(): MaybePromise<void>;
63
+ };
64
+
65
+ export type ProviderRuntimeContext = {
66
+ workflow: string;
67
+ nodePath: string;
68
+ emit: EventHandler;
69
+ interaction: {
70
+ present<Result>(session: ProviderInteractionSession<Result>): Promise<Result>;
71
+ };
72
+ local: LocalWorkspaceRuntime;
73
+ metadata(metadata: JsonObject): void;
74
+ };
75
+
76
+ export interface WorkflowProviderController<Runtime = unknown> {
77
+ readonly providerId: string;
78
+ runtime(context: ProviderRuntimeContext): MaybePromise<Runtime>;
79
+ validateArtifact?(ref: JsonValue): MaybePromise<boolean>;
80
+ }
81
+
82
+ export type ProviderFactoryInput = {
83
+ provider: LoadedProviderDefinition;
84
+ storage: ProviderStorage;
85
+ hostStorage: ProviderStorage;
86
+ local: LocalWorkspaceRuntime;
87
+ };
88
+
89
+ export type ProviderFactory = (
90
+ input: ProviderFactoryInput,
91
+ ) => WorkflowProviderController | Promise<WorkflowProviderController>;
92
+
93
+ export type ProviderStorageRecord<Value extends JsonValue = JsonValue> = {
94
+ providerId: string;
95
+ key: string;
96
+ value: Value;
97
+ createdAt: string;
98
+ updatedAt: string;
99
+ };
100
+
101
+ export interface ProviderStorage {
102
+ get<Value extends JsonValue = JsonValue>(key: string): ProviderStorageRecord<Value> | undefined;
103
+ set<Value extends JsonValue = JsonValue>(key: string, value: Value): ProviderStorageRecord<Value>;
104
+ delete(key: string): void;
105
+ entries(prefix?: string): ProviderStorageRecord[];
106
+ }
107
+
108
+ export type BaseProviderPlugin = {
109
+ providerId: string;
110
+ createProvider(input: ProviderFactoryInput): WorkflowProviderController | Promise<WorkflowProviderController>;
111
+ };
112
+
113
+ export type DevMachineProvider = BaseDevMachineProvider;