@khal-os/types 1.0.6 → 1.0.12
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.cjs +81 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -1
- package/dist/index.d.ts +120 -1
- package/dist/index.js +77 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -1
package/dist/index.cjs
CHANGED
|
@@ -20,14 +20,93 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
KhalAppEntrySchema: () => KhalAppEntrySchema,
|
|
24
|
+
KhalAppManifestSchema: () => KhalAppManifestSchema,
|
|
25
|
+
ROLE_HIERARCHY: () => ROLE_HIERARCHY,
|
|
26
|
+
validateManifest: () => validateManifest
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(index_exports);
|
|
26
29
|
|
|
30
|
+
// src/manifest.ts
|
|
31
|
+
var import_zod = require("zod");
|
|
32
|
+
var KhalPermission = import_zod.z.enum([
|
|
33
|
+
"nats:publish",
|
|
34
|
+
"nats:subscribe",
|
|
35
|
+
"files:read",
|
|
36
|
+
"files:write",
|
|
37
|
+
"pty:spawn",
|
|
38
|
+
"http:fetch",
|
|
39
|
+
"system:clipboard",
|
|
40
|
+
"system:notifications"
|
|
41
|
+
]);
|
|
42
|
+
var KhalServiceSpec = import_zod.z.object({
|
|
43
|
+
name: import_zod.z.string(),
|
|
44
|
+
command: import_zod.z.string().optional(),
|
|
45
|
+
entry: import_zod.z.string().optional(),
|
|
46
|
+
runtime: import_zod.z.enum(["node", "bun", "python"]).optional(),
|
|
47
|
+
ports: import_zod.z.array(import_zod.z.number()).optional(),
|
|
48
|
+
health: import_zod.z.object({
|
|
49
|
+
type: import_zod.z.enum(["tcp", "http", "command"]),
|
|
50
|
+
target: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]),
|
|
51
|
+
interval: import_zod.z.number().optional(),
|
|
52
|
+
timeout: import_zod.z.number().optional()
|
|
53
|
+
}).optional()
|
|
54
|
+
});
|
|
55
|
+
var KhalWindowSpec = import_zod.z.object({
|
|
56
|
+
id: import_zod.z.string(),
|
|
57
|
+
title: import_zod.z.string().optional(),
|
|
58
|
+
width: import_zod.z.number().default(800),
|
|
59
|
+
height: import_zod.z.number().default(600),
|
|
60
|
+
resizable: import_zod.z.boolean().default(true)
|
|
61
|
+
});
|
|
62
|
+
var KhalAppEntrySchema = import_zod.z.object({
|
|
63
|
+
/** Unique app identifier within the bundle. */
|
|
64
|
+
id: import_zod.z.string(),
|
|
65
|
+
/** Human-readable app name. */
|
|
66
|
+
name: import_zod.z.string(),
|
|
67
|
+
/** Frontend package reference for this app. */
|
|
68
|
+
frontend: import_zod.z.object({
|
|
69
|
+
package: import_zod.z.string()
|
|
70
|
+
}).optional()
|
|
71
|
+
});
|
|
72
|
+
var KhalAppManifestSchema = import_zod.z.object({
|
|
73
|
+
$schema: import_zod.z.string().optional(),
|
|
74
|
+
id: import_zod.z.string(),
|
|
75
|
+
name: import_zod.z.string(),
|
|
76
|
+
version: import_zod.z.string(),
|
|
77
|
+
icon: import_zod.z.string(),
|
|
78
|
+
description: import_zod.z.string(),
|
|
79
|
+
author: import_zod.z.string(),
|
|
80
|
+
permissions: import_zod.z.array(KhalPermission),
|
|
81
|
+
services: import_zod.z.array(KhalServiceSpec).optional(),
|
|
82
|
+
windows: import_zod.z.array(KhalWindowSpec).optional(),
|
|
83
|
+
frontend: import_zod.z.object({
|
|
84
|
+
package: import_zod.z.string(),
|
|
85
|
+
entry: import_zod.z.string().default("default")
|
|
86
|
+
}).optional(),
|
|
87
|
+
backend: import_zod.z.object({
|
|
88
|
+
image: import_zod.z.string(),
|
|
89
|
+
helmChart: import_zod.z.string().optional(),
|
|
90
|
+
env: import_zod.z.record(import_zod.z.string(), import_zod.z.string()),
|
|
91
|
+
ports: import_zod.z.array(import_zod.z.number())
|
|
92
|
+
}).optional(),
|
|
93
|
+
/**
|
|
94
|
+
* When apps is present, the root frontend field is ignored —
|
|
95
|
+
* each entry has its own frontend.
|
|
96
|
+
*/
|
|
97
|
+
apps: import_zod.z.array(KhalAppEntrySchema).optional()
|
|
98
|
+
}).strict();
|
|
99
|
+
function validateManifest(raw) {
|
|
100
|
+
return KhalAppManifestSchema.parse(raw);
|
|
101
|
+
}
|
|
102
|
+
|
|
27
103
|
// src/roles.ts
|
|
28
104
|
var ROLE_HIERARCHY = ["member", "platform-dev", "platform-admin", "platform-owner"];
|
|
29
105
|
// Annotate the CommonJS export names for ESM import in node:
|
|
30
106
|
0 && (module.exports = {
|
|
31
|
-
|
|
107
|
+
KhalAppEntrySchema,
|
|
108
|
+
KhalAppManifestSchema,
|
|
109
|
+
ROLE_HIERARCHY,
|
|
110
|
+
validateManifest
|
|
32
111
|
});
|
|
33
112
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/roles.ts"],"sourcesContent":["export type { KhalAuth } from './auth';\nexport type {\n\tAppDeployConfig,\n\tAppDesktopConfig,\n\tAppEnvVar,\n\tAppManifest,\n\tAppManifestView,\n\tAppServiceConfig,\n\tAppTauriConfig,\n\tServiceHealthConfig,\n} from './manifest';\nexport type { ConnectionState } from './nats';\nexport type { Role } from './roles';\nexport { ROLE_HIERARCHY } from './roles';\n","/** Canonical role hierarchy from least to most privileged. */\nexport const ROLE_HIERARCHY = ['member', 'platform-dev', 'platform-admin', 'platform-owner'] as const;\nexport type Role = (typeof ROLE_HIERARCHY)[number];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCO,IAAM,iBAAiB,CAAC,UAAU,gBAAgB,kBAAkB,gBAAgB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/manifest.ts","../src/roles.ts"],"sourcesContent":["export type { KhalAuth } from './auth';\nexport type {\n\tAppDeployConfig,\n\tAppDesktopConfig,\n\tAppEnvVar,\n\tAppManifest,\n\tAppManifestView,\n\tAppServiceConfig,\n\tAppTauriConfig,\n\tKhalAppEntry,\n\tKhalAppManifest,\n\tKhalPermission,\n\tKhalServiceSpec,\n\tKhalWindowSpec,\n\tServiceHealthConfig,\n} from './manifest';\nexport {\n\tKhalAppEntrySchema,\n\tKhalAppManifestSchema,\n\tvalidateManifest,\n} from './manifest';\nexport type { ConnectionState } from './nats';\nexport type { Role } from './roles';\nexport { ROLE_HIERARCHY } from './roles';\n","import { z } from 'zod';\nimport type { Role } from './roles';\n\n/** Desktop integration metadata for an app. */\nexport interface AppDesktopConfig {\n\t/** Path to the app icon (relative to the public directory). */\n\ticon: string;\n\t/** Categories for desktop launcher grouping. */\n\tcategories: string[];\n\t/** Short description shown in the desktop launcher. */\n\tcomment: string;\n}\n\n/** A single view within an app manifest. */\nexport interface AppManifestView {\n\t/** Unique view identifier within the app. */\n\tid: string;\n\t/** Human-readable label for the view. */\n\tlabel: string;\n\t/** Permission string required to access this view. */\n\tpermission: string;\n\t/** Minimum role level required. */\n\tminRole: Role;\n\t/** NATS subject segment after `khal.<orgId>.` for this view's services. */\n\tnatsPrefix?: string;\n\t/** Default window dimensions. */\n\tdefaultSize: { width: number; height: number };\n\t/** Relative path to the view's React component. */\n\tcomponent: string;\n}\n\n/** Health check configuration for a service. */\nexport interface ServiceHealthConfig {\n\t/** Check type: tcp (connect to port), http (GET endpoint), command (run shell). */\n\ttype: 'tcp' | 'http' | 'command';\n\t/** Target: port number for tcp, URL for http, shell command for command. */\n\ttarget: string | number;\n\t/** Check interval in milliseconds (default: 30000). */\n\tinterval?: number;\n\t/** Timeout in milliseconds (default: 5000). */\n\ttimeout?: number;\n}\n\n/** Service declaration within an app manifest. */\nexport interface AppServiceConfig {\n\t/** Service name (must be unique across the app). */\n\tname: string;\n\t/** Shell command to start the service (alternative to entry). */\n\tcommand?: string;\n\t/** Entry point file path relative to the package root. */\n\tentry?: string;\n\t/** Runtime environment. */\n\truntime?: 'node' | 'python';\n\t/** Health check configuration. */\n\thealth?: ServiceHealthConfig;\n\t/** Restart policy. */\n\trestart?: 'always' | 'on-failure' | 'never';\n\t/** Ports the service binds to internally. Khal assigns proxy ports. */\n\tports?: number[];\n}\n\n/** Environment variable declaration for app configuration. */\nexport interface AppEnvVar {\n\t/** Variable name (e.g., \"API_KEY\"). */\n\tkey: string;\n\t/** Human-readable description shown in the config UI. */\n\tdescription: string;\n\t/** Whether the variable is required for the app to run. */\n\trequired: boolean;\n\t/** Default value if not configured. */\n\tdefault?: string;\n\t/** Value type — affects config UI rendering and validation. */\n\ttype?: 'string' | 'number' | 'boolean' | 'secret' | 'url';\n\t/** Storage: 'config' for plain ConfigMap, 'vault' for Kubernetes Secret. */\n\tvisibility?: 'config' | 'vault';\n}\n\n/** Kubernetes deployment configuration for apps with backends. */\nexport interface AppDeployConfig {\n\t/** Dockerfile path relative to app root (default: \"Dockerfile\"). */\n\tdockerfile?: string;\n\t/** Build args passed to docker build. */\n\tbuildArgs?: Record<string, string>;\n\t/** Container port the app listens on. */\n\tport?: number;\n\t/** Resource requests and limits for the pod. */\n\tresources?: {\n\t\trequests?: { cpu?: string; memory?: string };\n\t\tlimits?: { cpu?: string; memory?: string };\n\t};\n\t/** Replica count (default: 1). */\n\treplicas?: number;\n\t/** Health check path for k8s readiness/liveness probes. */\n\thealthPath?: string;\n\t/** Ingress configuration for per-app routing. */\n\tingress?: {\n\t\t/** Subdomain prefix: <value>.apps.<domain>. Defaults to app id. */\n\t\tsubdomain?: string;\n\t\t/** Additional path prefixes to route to this app. */\n\t\tpathPrefixes?: string[];\n\t};\n\t/** Horizontal Pod Autoscaler configuration. */\n\tautoscaling?: {\n\t\tenabled: boolean;\n\t\tminReplicas?: number;\n\t\tmaxReplicas?: number;\n\t\ttargetCPU?: number;\n\t};\n\t/** Environment sources injected at runtime from k8s resources. */\n\tenvFrom?: Array<{ secretRef?: string; configMapRef?: string }>;\n}\n\n/** Tauri standalone export configuration. */\nexport interface AppTauriConfig {\n\t/** Whether this app supports standalone Tauri export. */\n\texportable: boolean;\n\t/** Path to src-tauri/ directory (default: \"./src-tauri\"). */\n\ttauriDir?: string;\n\t/** App name for the exported binary. */\n\tappName?: string;\n\t/** App icon path relative to app root. */\n\ticon?: string;\n\t/** Window configuration for standalone mode. */\n\twindow?: { width?: number; height?: number; title?: string };\n}\n\n/**\n * Full app manifest — the type for `manifest.ts` files in KhalOS app packages.\n *\n * Every app package must export a default manifest conforming to this shape.\n * Use `defineManifest()` for compile-time validation and autocomplete.\n *\n * The JSON equivalent (`khal-app.json`) uses the same shape and is the\n * language-agnostic install-time contract that the marketplace reads.\n */\nexport interface AppManifest {\n\t/** Unique app identifier (must match the package directory name). */\n\tid: string;\n\t/** One or more views the app exposes. */\n\tviews: AppManifestView[];\n\t/** Desktop integration configuration. */\n\tdesktop: AppDesktopConfig;\n\t/** Backend services this app runs. Optional — pure UI apps have no services. */\n\tservices?: AppServiceConfig[];\n\n\t// ── v2 fields (all optional for backward compatibility) ──\n\n\t/** Schema version for forward compatibility (default: 1). */\n\tschemaVersion?: number;\n\t/** Human-readable app name. */\n\tname?: string;\n\t/** Semantic version of the app. */\n\tversion?: string;\n\t/** Short description for the marketplace listing. */\n\tdescription?: string;\n\t/** Author name or organization. */\n\tauthor?: string;\n\t/** SPDX license identifier. */\n\tlicense?: string;\n\t/** Source repository URL. */\n\trepository?: string;\n\t/** Minimum KhalOS host version required. */\n\tminHostVersion?: string;\n\t/** Environment variables the app needs — auto-generates config UI. */\n\tenv?: AppEnvVar[];\n\t/** Native Kubernetes deployment configuration. */\n\tdeploy?: AppDeployConfig;\n\t/** Tauri standalone export configuration. */\n\ttauri?: AppTauriConfig;\n}\n\n// ── Pack Contract Types (for standalone pack-* repos) ──\n\nexport const KhalPermission = z.enum([\n\t'nats:publish',\n\t'nats:subscribe',\n\t'files:read',\n\t'files:write',\n\t'pty:spawn',\n\t'http:fetch',\n\t'system:clipboard',\n\t'system:notifications',\n]);\nexport type KhalPermission = z.infer<typeof KhalPermission>;\n\nexport const KhalServiceSpec = z.object({\n\tname: z.string(),\n\tcommand: z.string().optional(),\n\tentry: z.string().optional(),\n\truntime: z.enum(['node', 'bun', 'python']).optional(),\n\tports: z.array(z.number()).optional(),\n\thealth: z\n\t\t.object({\n\t\t\ttype: z.enum(['tcp', 'http', 'command']),\n\t\t\ttarget: z.union([z.string(), z.number()]),\n\t\t\tinterval: z.number().optional(),\n\t\t\ttimeout: z.number().optional(),\n\t\t})\n\t\t.optional(),\n});\nexport type KhalServiceSpec = z.infer<typeof KhalServiceSpec>;\n\nexport const KhalWindowSpec = z.object({\n\tid: z.string(),\n\ttitle: z.string().optional(),\n\twidth: z.number().default(800),\n\theight: z.number().default(600),\n\tresizable: z.boolean().default(true),\n});\nexport type KhalWindowSpec = z.infer<typeof KhalWindowSpec>;\n\n/** A single app entry within a bundle pack manifest. */\nexport const KhalAppEntrySchema = z.object({\n\t/** Unique app identifier within the bundle. */\n\tid: z.string(),\n\t/** Human-readable app name. */\n\tname: z.string(),\n\t/** Frontend package reference for this app. */\n\tfrontend: z\n\t\t.object({\n\t\t\tpackage: z.string(),\n\t\t})\n\t\t.optional(),\n});\nexport type KhalAppEntry = z.infer<typeof KhalAppEntrySchema>;\n\nexport const KhalAppManifestSchema = z\n\t.object({\n\t\t$schema: z.string().optional(),\n\t\tid: z.string(),\n\t\tname: z.string(),\n\t\tversion: z.string(),\n\t\ticon: z.string(),\n\t\tdescription: z.string(),\n\t\tauthor: z.string(),\n\t\tpermissions: z.array(KhalPermission),\n\t\tservices: z.array(KhalServiceSpec).optional(),\n\t\twindows: z.array(KhalWindowSpec).optional(),\n\t\tfrontend: z\n\t\t\t.object({\n\t\t\t\tpackage: z.string(),\n\t\t\t\tentry: z.string().default('default'),\n\t\t\t})\n\t\t\t.optional(),\n\t\tbackend: z\n\t\t\t.object({\n\t\t\t\timage: z.string(),\n\t\t\t\thelmChart: z.string().optional(),\n\t\t\t\tenv: z.record(z.string(), z.string()),\n\t\t\t\tports: z.array(z.number()),\n\t\t\t})\n\t\t\t.optional(),\n\t\t/**\n\t\t * When apps is present, the root frontend field is ignored —\n\t\t * each entry has its own frontend.\n\t\t */\n\t\tapps: z.array(KhalAppEntrySchema).optional(),\n\t})\n\t.strict();\n\nexport type KhalAppManifest = z.infer<typeof KhalAppManifestSchema>;\n\n/** Validate a raw object as KhalAppManifest. Throws ZodError with detailed messages on failure. */\nexport function validateManifest(raw: unknown): KhalAppManifest {\n\treturn KhalAppManifestSchema.parse(raw);\n}\n","/** Canonical role hierarchy from least to most privileged. */\nexport const ROLE_HIERARCHY = ['member', 'platform-dev', 'platform-admin', 'platform-owner'] as const;\nexport type Role = (typeof ROLE_HIERARCHY)[number];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAAkB;AA6KX,IAAM,iBAAiB,aAAE,KAAK;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAGM,IAAM,kBAAkB,aAAE,OAAO;AAAA,EACvC,MAAM,aAAE,OAAO;AAAA,EACf,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,SAAS,aAAE,KAAK,CAAC,QAAQ,OAAO,QAAQ,CAAC,EAAE,SAAS;AAAA,EACpD,OAAO,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,QAAQ,aACN,OAAO;AAAA,IACP,MAAM,aAAE,KAAK,CAAC,OAAO,QAAQ,SAAS,CAAC;AAAA,IACvC,QAAQ,aAAE,MAAM,CAAC,aAAE,OAAO,GAAG,aAAE,OAAO,CAAC,CAAC;AAAA,IACxC,UAAU,aAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,CAAC,EACA,SAAS;AACZ,CAAC;AAGM,IAAM,iBAAiB,aAAE,OAAO;AAAA,EACtC,IAAI,aAAE,OAAO;AAAA,EACb,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,aAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,EAC7B,QAAQ,aAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,EAC9B,WAAW,aAAE,QAAQ,EAAE,QAAQ,IAAI;AACpC,CAAC;AAIM,IAAM,qBAAqB,aAAE,OAAO;AAAA;AAAA,EAE1C,IAAI,aAAE,OAAO;AAAA;AAAA,EAEb,MAAM,aAAE,OAAO;AAAA;AAAA,EAEf,UAAU,aACR,OAAO;AAAA,IACP,SAAS,aAAE,OAAO;AAAA,EACnB,CAAC,EACA,SAAS;AACZ,CAAC;AAGM,IAAM,wBAAwB,aACnC,OAAO;AAAA,EACP,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,IAAI,aAAE,OAAO;AAAA,EACb,MAAM,aAAE,OAAO;AAAA,EACf,SAAS,aAAE,OAAO;AAAA,EAClB,MAAM,aAAE,OAAO;AAAA,EACf,aAAa,aAAE,OAAO;AAAA,EACtB,QAAQ,aAAE,OAAO;AAAA,EACjB,aAAa,aAAE,MAAM,cAAc;AAAA,EACnC,UAAU,aAAE,MAAM,eAAe,EAAE,SAAS;AAAA,EAC5C,SAAS,aAAE,MAAM,cAAc,EAAE,SAAS;AAAA,EAC1C,UAAU,aACR,OAAO;AAAA,IACP,SAAS,aAAE,OAAO;AAAA,IAClB,OAAO,aAAE,OAAO,EAAE,QAAQ,SAAS;AAAA,EACpC,CAAC,EACA,SAAS;AAAA,EACX,SAAS,aACP,OAAO;AAAA,IACP,OAAO,aAAE,OAAO;AAAA,IAChB,WAAW,aAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,KAAK,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,OAAO,CAAC;AAAA,IACpC,OAAO,aAAE,MAAM,aAAE,OAAO,CAAC;AAAA,EAC1B,CAAC,EACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKX,MAAM,aAAE,MAAM,kBAAkB,EAAE,SAAS;AAC5C,CAAC,EACA,OAAO;AAKF,SAAS,iBAAiB,KAA+B;AAC/D,SAAO,sBAAsB,MAAM,GAAG;AACvC;;;ACxQO,IAAM,iBAAiB,CAAC,UAAU,gBAAgB,kBAAkB,gBAAgB;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
1
3
|
/** Authenticated user state returned by `useKhalAuth`. */
|
|
2
4
|
interface KhalAuth {
|
|
3
5
|
userId: string;
|
|
@@ -184,8 +186,125 @@ interface AppManifest {
|
|
|
184
186
|
/** Tauri standalone export configuration. */
|
|
185
187
|
tauri?: AppTauriConfig;
|
|
186
188
|
}
|
|
189
|
+
declare const KhalPermission: z.ZodEnum<{
|
|
190
|
+
"nats:publish": "nats:publish";
|
|
191
|
+
"nats:subscribe": "nats:subscribe";
|
|
192
|
+
"files:read": "files:read";
|
|
193
|
+
"files:write": "files:write";
|
|
194
|
+
"pty:spawn": "pty:spawn";
|
|
195
|
+
"http:fetch": "http:fetch";
|
|
196
|
+
"system:clipboard": "system:clipboard";
|
|
197
|
+
"system:notifications": "system:notifications";
|
|
198
|
+
}>;
|
|
199
|
+
type KhalPermission = z.infer<typeof KhalPermission>;
|
|
200
|
+
declare const KhalServiceSpec: z.ZodObject<{
|
|
201
|
+
name: z.ZodString;
|
|
202
|
+
command: z.ZodOptional<z.ZodString>;
|
|
203
|
+
entry: z.ZodOptional<z.ZodString>;
|
|
204
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
205
|
+
node: "node";
|
|
206
|
+
python: "python";
|
|
207
|
+
bun: "bun";
|
|
208
|
+
}>>;
|
|
209
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
210
|
+
health: z.ZodOptional<z.ZodObject<{
|
|
211
|
+
type: z.ZodEnum<{
|
|
212
|
+
tcp: "tcp";
|
|
213
|
+
http: "http";
|
|
214
|
+
command: "command";
|
|
215
|
+
}>;
|
|
216
|
+
target: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
217
|
+
interval: z.ZodOptional<z.ZodNumber>;
|
|
218
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
219
|
+
}, z.core.$strip>>;
|
|
220
|
+
}, z.core.$strip>;
|
|
221
|
+
type KhalServiceSpec = z.infer<typeof KhalServiceSpec>;
|
|
222
|
+
declare const KhalWindowSpec: z.ZodObject<{
|
|
223
|
+
id: z.ZodString;
|
|
224
|
+
title: z.ZodOptional<z.ZodString>;
|
|
225
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
226
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
227
|
+
resizable: z.ZodDefault<z.ZodBoolean>;
|
|
228
|
+
}, z.core.$strip>;
|
|
229
|
+
type KhalWindowSpec = z.infer<typeof KhalWindowSpec>;
|
|
230
|
+
/** A single app entry within a bundle pack manifest. */
|
|
231
|
+
declare const KhalAppEntrySchema: z.ZodObject<{
|
|
232
|
+
id: z.ZodString;
|
|
233
|
+
name: z.ZodString;
|
|
234
|
+
frontend: z.ZodOptional<z.ZodObject<{
|
|
235
|
+
package: z.ZodString;
|
|
236
|
+
}, z.core.$strip>>;
|
|
237
|
+
}, z.core.$strip>;
|
|
238
|
+
type KhalAppEntry = z.infer<typeof KhalAppEntrySchema>;
|
|
239
|
+
declare const KhalAppManifestSchema: z.ZodObject<{
|
|
240
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
241
|
+
id: z.ZodString;
|
|
242
|
+
name: z.ZodString;
|
|
243
|
+
version: z.ZodString;
|
|
244
|
+
icon: z.ZodString;
|
|
245
|
+
description: z.ZodString;
|
|
246
|
+
author: z.ZodString;
|
|
247
|
+
permissions: z.ZodArray<z.ZodEnum<{
|
|
248
|
+
"nats:publish": "nats:publish";
|
|
249
|
+
"nats:subscribe": "nats:subscribe";
|
|
250
|
+
"files:read": "files:read";
|
|
251
|
+
"files:write": "files:write";
|
|
252
|
+
"pty:spawn": "pty:spawn";
|
|
253
|
+
"http:fetch": "http:fetch";
|
|
254
|
+
"system:clipboard": "system:clipboard";
|
|
255
|
+
"system:notifications": "system:notifications";
|
|
256
|
+
}>>;
|
|
257
|
+
services: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
258
|
+
name: z.ZodString;
|
|
259
|
+
command: z.ZodOptional<z.ZodString>;
|
|
260
|
+
entry: z.ZodOptional<z.ZodString>;
|
|
261
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
262
|
+
node: "node";
|
|
263
|
+
python: "python";
|
|
264
|
+
bun: "bun";
|
|
265
|
+
}>>;
|
|
266
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
267
|
+
health: z.ZodOptional<z.ZodObject<{
|
|
268
|
+
type: z.ZodEnum<{
|
|
269
|
+
tcp: "tcp";
|
|
270
|
+
http: "http";
|
|
271
|
+
command: "command";
|
|
272
|
+
}>;
|
|
273
|
+
target: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
274
|
+
interval: z.ZodOptional<z.ZodNumber>;
|
|
275
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
276
|
+
}, z.core.$strip>>;
|
|
277
|
+
}, z.core.$strip>>>;
|
|
278
|
+
windows: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
279
|
+
id: z.ZodString;
|
|
280
|
+
title: z.ZodOptional<z.ZodString>;
|
|
281
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
282
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
283
|
+
resizable: z.ZodDefault<z.ZodBoolean>;
|
|
284
|
+
}, z.core.$strip>>>;
|
|
285
|
+
frontend: z.ZodOptional<z.ZodObject<{
|
|
286
|
+
package: z.ZodString;
|
|
287
|
+
entry: z.ZodDefault<z.ZodString>;
|
|
288
|
+
}, z.core.$strip>>;
|
|
289
|
+
backend: z.ZodOptional<z.ZodObject<{
|
|
290
|
+
image: z.ZodString;
|
|
291
|
+
helmChart: z.ZodOptional<z.ZodString>;
|
|
292
|
+
env: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
293
|
+
ports: z.ZodArray<z.ZodNumber>;
|
|
294
|
+
}, z.core.$strip>>;
|
|
295
|
+
apps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
296
|
+
id: z.ZodString;
|
|
297
|
+
name: z.ZodString;
|
|
298
|
+
frontend: z.ZodOptional<z.ZodObject<{
|
|
299
|
+
package: z.ZodString;
|
|
300
|
+
}, z.core.$strip>>;
|
|
301
|
+
}, z.core.$strip>>>;
|
|
302
|
+
}, z.core.$strict>;
|
|
303
|
+
type KhalAppManifest = z.infer<typeof KhalAppManifestSchema>;
|
|
304
|
+
/** Validate a raw object as KhalAppManifest. Throws ZodError with detailed messages on failure. */
|
|
305
|
+
declare function validateManifest(raw: unknown): KhalAppManifest;
|
|
187
306
|
|
|
188
307
|
/** Connection states reported by the WS relay. */
|
|
189
308
|
type ConnectionState = 'connected' | 'reconnecting' | 'disconnected' | 'auth_expired' | 'version_mismatch';
|
|
190
309
|
|
|
191
|
-
export { type AppDeployConfig, type AppDesktopConfig, type AppEnvVar, type AppManifest, type AppManifestView, type AppServiceConfig, type AppTauriConfig, type ConnectionState, type KhalAuth, ROLE_HIERARCHY, type Role, type ServiceHealthConfig };
|
|
310
|
+
export { type AppDeployConfig, type AppDesktopConfig, type AppEnvVar, type AppManifest, type AppManifestView, type AppServiceConfig, type AppTauriConfig, type ConnectionState, type KhalAppEntry, KhalAppEntrySchema, type KhalAppManifest, KhalAppManifestSchema, type KhalAuth, KhalPermission, KhalServiceSpec, KhalWindowSpec, ROLE_HIERARCHY, type Role, type ServiceHealthConfig, validateManifest };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
1
3
|
/** Authenticated user state returned by `useKhalAuth`. */
|
|
2
4
|
interface KhalAuth {
|
|
3
5
|
userId: string;
|
|
@@ -184,8 +186,125 @@ interface AppManifest {
|
|
|
184
186
|
/** Tauri standalone export configuration. */
|
|
185
187
|
tauri?: AppTauriConfig;
|
|
186
188
|
}
|
|
189
|
+
declare const KhalPermission: z.ZodEnum<{
|
|
190
|
+
"nats:publish": "nats:publish";
|
|
191
|
+
"nats:subscribe": "nats:subscribe";
|
|
192
|
+
"files:read": "files:read";
|
|
193
|
+
"files:write": "files:write";
|
|
194
|
+
"pty:spawn": "pty:spawn";
|
|
195
|
+
"http:fetch": "http:fetch";
|
|
196
|
+
"system:clipboard": "system:clipboard";
|
|
197
|
+
"system:notifications": "system:notifications";
|
|
198
|
+
}>;
|
|
199
|
+
type KhalPermission = z.infer<typeof KhalPermission>;
|
|
200
|
+
declare const KhalServiceSpec: z.ZodObject<{
|
|
201
|
+
name: z.ZodString;
|
|
202
|
+
command: z.ZodOptional<z.ZodString>;
|
|
203
|
+
entry: z.ZodOptional<z.ZodString>;
|
|
204
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
205
|
+
node: "node";
|
|
206
|
+
python: "python";
|
|
207
|
+
bun: "bun";
|
|
208
|
+
}>>;
|
|
209
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
210
|
+
health: z.ZodOptional<z.ZodObject<{
|
|
211
|
+
type: z.ZodEnum<{
|
|
212
|
+
tcp: "tcp";
|
|
213
|
+
http: "http";
|
|
214
|
+
command: "command";
|
|
215
|
+
}>;
|
|
216
|
+
target: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
217
|
+
interval: z.ZodOptional<z.ZodNumber>;
|
|
218
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
219
|
+
}, z.core.$strip>>;
|
|
220
|
+
}, z.core.$strip>;
|
|
221
|
+
type KhalServiceSpec = z.infer<typeof KhalServiceSpec>;
|
|
222
|
+
declare const KhalWindowSpec: z.ZodObject<{
|
|
223
|
+
id: z.ZodString;
|
|
224
|
+
title: z.ZodOptional<z.ZodString>;
|
|
225
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
226
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
227
|
+
resizable: z.ZodDefault<z.ZodBoolean>;
|
|
228
|
+
}, z.core.$strip>;
|
|
229
|
+
type KhalWindowSpec = z.infer<typeof KhalWindowSpec>;
|
|
230
|
+
/** A single app entry within a bundle pack manifest. */
|
|
231
|
+
declare const KhalAppEntrySchema: z.ZodObject<{
|
|
232
|
+
id: z.ZodString;
|
|
233
|
+
name: z.ZodString;
|
|
234
|
+
frontend: z.ZodOptional<z.ZodObject<{
|
|
235
|
+
package: z.ZodString;
|
|
236
|
+
}, z.core.$strip>>;
|
|
237
|
+
}, z.core.$strip>;
|
|
238
|
+
type KhalAppEntry = z.infer<typeof KhalAppEntrySchema>;
|
|
239
|
+
declare const KhalAppManifestSchema: z.ZodObject<{
|
|
240
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
241
|
+
id: z.ZodString;
|
|
242
|
+
name: z.ZodString;
|
|
243
|
+
version: z.ZodString;
|
|
244
|
+
icon: z.ZodString;
|
|
245
|
+
description: z.ZodString;
|
|
246
|
+
author: z.ZodString;
|
|
247
|
+
permissions: z.ZodArray<z.ZodEnum<{
|
|
248
|
+
"nats:publish": "nats:publish";
|
|
249
|
+
"nats:subscribe": "nats:subscribe";
|
|
250
|
+
"files:read": "files:read";
|
|
251
|
+
"files:write": "files:write";
|
|
252
|
+
"pty:spawn": "pty:spawn";
|
|
253
|
+
"http:fetch": "http:fetch";
|
|
254
|
+
"system:clipboard": "system:clipboard";
|
|
255
|
+
"system:notifications": "system:notifications";
|
|
256
|
+
}>>;
|
|
257
|
+
services: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
258
|
+
name: z.ZodString;
|
|
259
|
+
command: z.ZodOptional<z.ZodString>;
|
|
260
|
+
entry: z.ZodOptional<z.ZodString>;
|
|
261
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
262
|
+
node: "node";
|
|
263
|
+
python: "python";
|
|
264
|
+
bun: "bun";
|
|
265
|
+
}>>;
|
|
266
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
267
|
+
health: z.ZodOptional<z.ZodObject<{
|
|
268
|
+
type: z.ZodEnum<{
|
|
269
|
+
tcp: "tcp";
|
|
270
|
+
http: "http";
|
|
271
|
+
command: "command";
|
|
272
|
+
}>;
|
|
273
|
+
target: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
274
|
+
interval: z.ZodOptional<z.ZodNumber>;
|
|
275
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
276
|
+
}, z.core.$strip>>;
|
|
277
|
+
}, z.core.$strip>>>;
|
|
278
|
+
windows: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
279
|
+
id: z.ZodString;
|
|
280
|
+
title: z.ZodOptional<z.ZodString>;
|
|
281
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
282
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
283
|
+
resizable: z.ZodDefault<z.ZodBoolean>;
|
|
284
|
+
}, z.core.$strip>>>;
|
|
285
|
+
frontend: z.ZodOptional<z.ZodObject<{
|
|
286
|
+
package: z.ZodString;
|
|
287
|
+
entry: z.ZodDefault<z.ZodString>;
|
|
288
|
+
}, z.core.$strip>>;
|
|
289
|
+
backend: z.ZodOptional<z.ZodObject<{
|
|
290
|
+
image: z.ZodString;
|
|
291
|
+
helmChart: z.ZodOptional<z.ZodString>;
|
|
292
|
+
env: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
293
|
+
ports: z.ZodArray<z.ZodNumber>;
|
|
294
|
+
}, z.core.$strip>>;
|
|
295
|
+
apps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
296
|
+
id: z.ZodString;
|
|
297
|
+
name: z.ZodString;
|
|
298
|
+
frontend: z.ZodOptional<z.ZodObject<{
|
|
299
|
+
package: z.ZodString;
|
|
300
|
+
}, z.core.$strip>>;
|
|
301
|
+
}, z.core.$strip>>>;
|
|
302
|
+
}, z.core.$strict>;
|
|
303
|
+
type KhalAppManifest = z.infer<typeof KhalAppManifestSchema>;
|
|
304
|
+
/** Validate a raw object as KhalAppManifest. Throws ZodError with detailed messages on failure. */
|
|
305
|
+
declare function validateManifest(raw: unknown): KhalAppManifest;
|
|
187
306
|
|
|
188
307
|
/** Connection states reported by the WS relay. */
|
|
189
308
|
type ConnectionState = 'connected' | 'reconnecting' | 'disconnected' | 'auth_expired' | 'version_mismatch';
|
|
190
309
|
|
|
191
|
-
export { type AppDeployConfig, type AppDesktopConfig, type AppEnvVar, type AppManifest, type AppManifestView, type AppServiceConfig, type AppTauriConfig, type ConnectionState, type KhalAuth, ROLE_HIERARCHY, type Role, type ServiceHealthConfig };
|
|
310
|
+
export { type AppDeployConfig, type AppDesktopConfig, type AppEnvVar, type AppManifest, type AppManifestView, type AppServiceConfig, type AppTauriConfig, type ConnectionState, type KhalAppEntry, KhalAppEntrySchema, type KhalAppManifest, KhalAppManifestSchema, type KhalAuth, KhalPermission, KhalServiceSpec, KhalWindowSpec, ROLE_HIERARCHY, type Role, type ServiceHealthConfig, validateManifest };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,82 @@
|
|
|
1
|
+
// src/manifest.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var KhalPermission = z.enum([
|
|
4
|
+
"nats:publish",
|
|
5
|
+
"nats:subscribe",
|
|
6
|
+
"files:read",
|
|
7
|
+
"files:write",
|
|
8
|
+
"pty:spawn",
|
|
9
|
+
"http:fetch",
|
|
10
|
+
"system:clipboard",
|
|
11
|
+
"system:notifications"
|
|
12
|
+
]);
|
|
13
|
+
var KhalServiceSpec = z.object({
|
|
14
|
+
name: z.string(),
|
|
15
|
+
command: z.string().optional(),
|
|
16
|
+
entry: z.string().optional(),
|
|
17
|
+
runtime: z.enum(["node", "bun", "python"]).optional(),
|
|
18
|
+
ports: z.array(z.number()).optional(),
|
|
19
|
+
health: z.object({
|
|
20
|
+
type: z.enum(["tcp", "http", "command"]),
|
|
21
|
+
target: z.union([z.string(), z.number()]),
|
|
22
|
+
interval: z.number().optional(),
|
|
23
|
+
timeout: z.number().optional()
|
|
24
|
+
}).optional()
|
|
25
|
+
});
|
|
26
|
+
var KhalWindowSpec = z.object({
|
|
27
|
+
id: z.string(),
|
|
28
|
+
title: z.string().optional(),
|
|
29
|
+
width: z.number().default(800),
|
|
30
|
+
height: z.number().default(600),
|
|
31
|
+
resizable: z.boolean().default(true)
|
|
32
|
+
});
|
|
33
|
+
var KhalAppEntrySchema = z.object({
|
|
34
|
+
/** Unique app identifier within the bundle. */
|
|
35
|
+
id: z.string(),
|
|
36
|
+
/** Human-readable app name. */
|
|
37
|
+
name: z.string(),
|
|
38
|
+
/** Frontend package reference for this app. */
|
|
39
|
+
frontend: z.object({
|
|
40
|
+
package: z.string()
|
|
41
|
+
}).optional()
|
|
42
|
+
});
|
|
43
|
+
var KhalAppManifestSchema = z.object({
|
|
44
|
+
$schema: z.string().optional(),
|
|
45
|
+
id: z.string(),
|
|
46
|
+
name: z.string(),
|
|
47
|
+
version: z.string(),
|
|
48
|
+
icon: z.string(),
|
|
49
|
+
description: z.string(),
|
|
50
|
+
author: z.string(),
|
|
51
|
+
permissions: z.array(KhalPermission),
|
|
52
|
+
services: z.array(KhalServiceSpec).optional(),
|
|
53
|
+
windows: z.array(KhalWindowSpec).optional(),
|
|
54
|
+
frontend: z.object({
|
|
55
|
+
package: z.string(),
|
|
56
|
+
entry: z.string().default("default")
|
|
57
|
+
}).optional(),
|
|
58
|
+
backend: z.object({
|
|
59
|
+
image: z.string(),
|
|
60
|
+
helmChart: z.string().optional(),
|
|
61
|
+
env: z.record(z.string(), z.string()),
|
|
62
|
+
ports: z.array(z.number())
|
|
63
|
+
}).optional(),
|
|
64
|
+
/**
|
|
65
|
+
* When apps is present, the root frontend field is ignored —
|
|
66
|
+
* each entry has its own frontend.
|
|
67
|
+
*/
|
|
68
|
+
apps: z.array(KhalAppEntrySchema).optional()
|
|
69
|
+
}).strict();
|
|
70
|
+
function validateManifest(raw) {
|
|
71
|
+
return KhalAppManifestSchema.parse(raw);
|
|
72
|
+
}
|
|
73
|
+
|
|
1
74
|
// src/roles.ts
|
|
2
75
|
var ROLE_HIERARCHY = ["member", "platform-dev", "platform-admin", "platform-owner"];
|
|
3
76
|
export {
|
|
4
|
-
|
|
77
|
+
KhalAppEntrySchema,
|
|
78
|
+
KhalAppManifestSchema,
|
|
79
|
+
ROLE_HIERARCHY,
|
|
80
|
+
validateManifest
|
|
5
81
|
};
|
|
6
82
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/roles.ts"],"sourcesContent":["/** Canonical role hierarchy from least to most privileged. */\nexport const ROLE_HIERARCHY = ['member', 'platform-dev', 'platform-admin', 'platform-owner'] as const;\nexport type Role = (typeof ROLE_HIERARCHY)[number];\n"],"mappings":";AACO,IAAM,iBAAiB,CAAC,UAAU,gBAAgB,kBAAkB,gBAAgB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/manifest.ts","../src/roles.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { Role } from './roles';\n\n/** Desktop integration metadata for an app. */\nexport interface AppDesktopConfig {\n\t/** Path to the app icon (relative to the public directory). */\n\ticon: string;\n\t/** Categories for desktop launcher grouping. */\n\tcategories: string[];\n\t/** Short description shown in the desktop launcher. */\n\tcomment: string;\n}\n\n/** A single view within an app manifest. */\nexport interface AppManifestView {\n\t/** Unique view identifier within the app. */\n\tid: string;\n\t/** Human-readable label for the view. */\n\tlabel: string;\n\t/** Permission string required to access this view. */\n\tpermission: string;\n\t/** Minimum role level required. */\n\tminRole: Role;\n\t/** NATS subject segment after `khal.<orgId>.` for this view's services. */\n\tnatsPrefix?: string;\n\t/** Default window dimensions. */\n\tdefaultSize: { width: number; height: number };\n\t/** Relative path to the view's React component. */\n\tcomponent: string;\n}\n\n/** Health check configuration for a service. */\nexport interface ServiceHealthConfig {\n\t/** Check type: tcp (connect to port), http (GET endpoint), command (run shell). */\n\ttype: 'tcp' | 'http' | 'command';\n\t/** Target: port number for tcp, URL for http, shell command for command. */\n\ttarget: string | number;\n\t/** Check interval in milliseconds (default: 30000). */\n\tinterval?: number;\n\t/** Timeout in milliseconds (default: 5000). */\n\ttimeout?: number;\n}\n\n/** Service declaration within an app manifest. */\nexport interface AppServiceConfig {\n\t/** Service name (must be unique across the app). */\n\tname: string;\n\t/** Shell command to start the service (alternative to entry). */\n\tcommand?: string;\n\t/** Entry point file path relative to the package root. */\n\tentry?: string;\n\t/** Runtime environment. */\n\truntime?: 'node' | 'python';\n\t/** Health check configuration. */\n\thealth?: ServiceHealthConfig;\n\t/** Restart policy. */\n\trestart?: 'always' | 'on-failure' | 'never';\n\t/** Ports the service binds to internally. Khal assigns proxy ports. */\n\tports?: number[];\n}\n\n/** Environment variable declaration for app configuration. */\nexport interface AppEnvVar {\n\t/** Variable name (e.g., \"API_KEY\"). */\n\tkey: string;\n\t/** Human-readable description shown in the config UI. */\n\tdescription: string;\n\t/** Whether the variable is required for the app to run. */\n\trequired: boolean;\n\t/** Default value if not configured. */\n\tdefault?: string;\n\t/** Value type — affects config UI rendering and validation. */\n\ttype?: 'string' | 'number' | 'boolean' | 'secret' | 'url';\n\t/** Storage: 'config' for plain ConfigMap, 'vault' for Kubernetes Secret. */\n\tvisibility?: 'config' | 'vault';\n}\n\n/** Kubernetes deployment configuration for apps with backends. */\nexport interface AppDeployConfig {\n\t/** Dockerfile path relative to app root (default: \"Dockerfile\"). */\n\tdockerfile?: string;\n\t/** Build args passed to docker build. */\n\tbuildArgs?: Record<string, string>;\n\t/** Container port the app listens on. */\n\tport?: number;\n\t/** Resource requests and limits for the pod. */\n\tresources?: {\n\t\trequests?: { cpu?: string; memory?: string };\n\t\tlimits?: { cpu?: string; memory?: string };\n\t};\n\t/** Replica count (default: 1). */\n\treplicas?: number;\n\t/** Health check path for k8s readiness/liveness probes. */\n\thealthPath?: string;\n\t/** Ingress configuration for per-app routing. */\n\tingress?: {\n\t\t/** Subdomain prefix: <value>.apps.<domain>. Defaults to app id. */\n\t\tsubdomain?: string;\n\t\t/** Additional path prefixes to route to this app. */\n\t\tpathPrefixes?: string[];\n\t};\n\t/** Horizontal Pod Autoscaler configuration. */\n\tautoscaling?: {\n\t\tenabled: boolean;\n\t\tminReplicas?: number;\n\t\tmaxReplicas?: number;\n\t\ttargetCPU?: number;\n\t};\n\t/** Environment sources injected at runtime from k8s resources. */\n\tenvFrom?: Array<{ secretRef?: string; configMapRef?: string }>;\n}\n\n/** Tauri standalone export configuration. */\nexport interface AppTauriConfig {\n\t/** Whether this app supports standalone Tauri export. */\n\texportable: boolean;\n\t/** Path to src-tauri/ directory (default: \"./src-tauri\"). */\n\ttauriDir?: string;\n\t/** App name for the exported binary. */\n\tappName?: string;\n\t/** App icon path relative to app root. */\n\ticon?: string;\n\t/** Window configuration for standalone mode. */\n\twindow?: { width?: number; height?: number; title?: string };\n}\n\n/**\n * Full app manifest — the type for `manifest.ts` files in KhalOS app packages.\n *\n * Every app package must export a default manifest conforming to this shape.\n * Use `defineManifest()` for compile-time validation and autocomplete.\n *\n * The JSON equivalent (`khal-app.json`) uses the same shape and is the\n * language-agnostic install-time contract that the marketplace reads.\n */\nexport interface AppManifest {\n\t/** Unique app identifier (must match the package directory name). */\n\tid: string;\n\t/** One or more views the app exposes. */\n\tviews: AppManifestView[];\n\t/** Desktop integration configuration. */\n\tdesktop: AppDesktopConfig;\n\t/** Backend services this app runs. Optional — pure UI apps have no services. */\n\tservices?: AppServiceConfig[];\n\n\t// ── v2 fields (all optional for backward compatibility) ──\n\n\t/** Schema version for forward compatibility (default: 1). */\n\tschemaVersion?: number;\n\t/** Human-readable app name. */\n\tname?: string;\n\t/** Semantic version of the app. */\n\tversion?: string;\n\t/** Short description for the marketplace listing. */\n\tdescription?: string;\n\t/** Author name or organization. */\n\tauthor?: string;\n\t/** SPDX license identifier. */\n\tlicense?: string;\n\t/** Source repository URL. */\n\trepository?: string;\n\t/** Minimum KhalOS host version required. */\n\tminHostVersion?: string;\n\t/** Environment variables the app needs — auto-generates config UI. */\n\tenv?: AppEnvVar[];\n\t/** Native Kubernetes deployment configuration. */\n\tdeploy?: AppDeployConfig;\n\t/** Tauri standalone export configuration. */\n\ttauri?: AppTauriConfig;\n}\n\n// ── Pack Contract Types (for standalone pack-* repos) ──\n\nexport const KhalPermission = z.enum([\n\t'nats:publish',\n\t'nats:subscribe',\n\t'files:read',\n\t'files:write',\n\t'pty:spawn',\n\t'http:fetch',\n\t'system:clipboard',\n\t'system:notifications',\n]);\nexport type KhalPermission = z.infer<typeof KhalPermission>;\n\nexport const KhalServiceSpec = z.object({\n\tname: z.string(),\n\tcommand: z.string().optional(),\n\tentry: z.string().optional(),\n\truntime: z.enum(['node', 'bun', 'python']).optional(),\n\tports: z.array(z.number()).optional(),\n\thealth: z\n\t\t.object({\n\t\t\ttype: z.enum(['tcp', 'http', 'command']),\n\t\t\ttarget: z.union([z.string(), z.number()]),\n\t\t\tinterval: z.number().optional(),\n\t\t\ttimeout: z.number().optional(),\n\t\t})\n\t\t.optional(),\n});\nexport type KhalServiceSpec = z.infer<typeof KhalServiceSpec>;\n\nexport const KhalWindowSpec = z.object({\n\tid: z.string(),\n\ttitle: z.string().optional(),\n\twidth: z.number().default(800),\n\theight: z.number().default(600),\n\tresizable: z.boolean().default(true),\n});\nexport type KhalWindowSpec = z.infer<typeof KhalWindowSpec>;\n\n/** A single app entry within a bundle pack manifest. */\nexport const KhalAppEntrySchema = z.object({\n\t/** Unique app identifier within the bundle. */\n\tid: z.string(),\n\t/** Human-readable app name. */\n\tname: z.string(),\n\t/** Frontend package reference for this app. */\n\tfrontend: z\n\t\t.object({\n\t\t\tpackage: z.string(),\n\t\t})\n\t\t.optional(),\n});\nexport type KhalAppEntry = z.infer<typeof KhalAppEntrySchema>;\n\nexport const KhalAppManifestSchema = z\n\t.object({\n\t\t$schema: z.string().optional(),\n\t\tid: z.string(),\n\t\tname: z.string(),\n\t\tversion: z.string(),\n\t\ticon: z.string(),\n\t\tdescription: z.string(),\n\t\tauthor: z.string(),\n\t\tpermissions: z.array(KhalPermission),\n\t\tservices: z.array(KhalServiceSpec).optional(),\n\t\twindows: z.array(KhalWindowSpec).optional(),\n\t\tfrontend: z\n\t\t\t.object({\n\t\t\t\tpackage: z.string(),\n\t\t\t\tentry: z.string().default('default'),\n\t\t\t})\n\t\t\t.optional(),\n\t\tbackend: z\n\t\t\t.object({\n\t\t\t\timage: z.string(),\n\t\t\t\thelmChart: z.string().optional(),\n\t\t\t\tenv: z.record(z.string(), z.string()),\n\t\t\t\tports: z.array(z.number()),\n\t\t\t})\n\t\t\t.optional(),\n\t\t/**\n\t\t * When apps is present, the root frontend field is ignored —\n\t\t * each entry has its own frontend.\n\t\t */\n\t\tapps: z.array(KhalAppEntrySchema).optional(),\n\t})\n\t.strict();\n\nexport type KhalAppManifest = z.infer<typeof KhalAppManifestSchema>;\n\n/** Validate a raw object as KhalAppManifest. Throws ZodError with detailed messages on failure. */\nexport function validateManifest(raw: unknown): KhalAppManifest {\n\treturn KhalAppManifestSchema.parse(raw);\n}\n","/** Canonical role hierarchy from least to most privileged. */\nexport const ROLE_HIERARCHY = ['member', 'platform-dev', 'platform-admin', 'platform-owner'] as const;\nexport type Role = (typeof ROLE_HIERARCHY)[number];\n"],"mappings":";AAAA,SAAS,SAAS;AA6KX,IAAM,iBAAiB,EAAE,KAAK;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAGM,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACvC,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,SAAS,EAAE,KAAK,CAAC,QAAQ,OAAO,QAAQ,CAAC,EAAE,SAAS;AAAA,EACpD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,QAAQ,EACN,OAAO;AAAA,IACP,MAAM,EAAE,KAAK,CAAC,OAAO,QAAQ,SAAS,CAAC;AAAA,IACvC,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,IACxC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,CAAC,EACA,SAAS;AACZ,CAAC;AAGM,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACtC,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,EAC7B,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,EAC9B,WAAW,EAAE,QAAQ,EAAE,QAAQ,IAAI;AACpC,CAAC;AAIM,IAAM,qBAAqB,EAAE,OAAO;AAAA;AAAA,EAE1C,IAAI,EAAE,OAAO;AAAA;AAAA,EAEb,MAAM,EAAE,OAAO;AAAA;AAAA,EAEf,UAAU,EACR,OAAO;AAAA,IACP,SAAS,EAAE,OAAO;AAAA,EACnB,CAAC,EACA,SAAS;AACZ,CAAC;AAGM,IAAM,wBAAwB,EACnC,OAAO;AAAA,EACP,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,EAAE,OAAO;AAAA,EAClB,MAAM,EAAE,OAAO;AAAA,EACf,aAAa,EAAE,OAAO;AAAA,EACtB,QAAQ,EAAE,OAAO;AAAA,EACjB,aAAa,EAAE,MAAM,cAAc;AAAA,EACnC,UAAU,EAAE,MAAM,eAAe,EAAE,SAAS;AAAA,EAC5C,SAAS,EAAE,MAAM,cAAc,EAAE,SAAS;AAAA,EAC1C,UAAU,EACR,OAAO;AAAA,IACP,SAAS,EAAE,OAAO;AAAA,IAClB,OAAO,EAAE,OAAO,EAAE,QAAQ,SAAS;AAAA,EACpC,CAAC,EACA,SAAS;AAAA,EACX,SAAS,EACP,OAAO;AAAA,IACP,OAAO,EAAE,OAAO;AAAA,IAChB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AAAA,IACpC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EAC1B,CAAC,EACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKX,MAAM,EAAE,MAAM,kBAAkB,EAAE,SAAS;AAC5C,CAAC,EACA,OAAO;AAKF,SAAS,iBAAiB,KAA+B;AAC/D,SAAO,sBAAsB,MAAM,GAAG;AACvC;;;ACxQO,IAAM,iBAAiB,CAAC,UAAU,gBAAgB,kBAAkB,gBAAgB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khal-os/types",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -23,10 +23,19 @@
|
|
|
23
23
|
"README.md",
|
|
24
24
|
"LICENSE"
|
|
25
25
|
],
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/khal-os/app-kit.git",
|
|
29
|
+
"directory": "packages/types"
|
|
30
|
+
},
|
|
26
31
|
"publishConfig": {
|
|
32
|
+
"registry": "https://registry.npmjs.org/",
|
|
27
33
|
"access": "public"
|
|
28
34
|
},
|
|
29
35
|
"license": "Elastic-2.0",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"zod": "^4.3.6"
|
|
38
|
+
},
|
|
30
39
|
"scripts": {
|
|
31
40
|
"build": "tsup"
|
|
32
41
|
}
|