dsh-env-manager-plugin 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +273 -3
  3. package/client.js +2581 -0
  4. package/cordis.patch.yml +4 -0
  5. package/docs/00-project/current-state.md +272 -0
  6. package/docs/00-project/glossary.md +215 -0
  7. package/docs/00-project/project-brief.md +114 -0
  8. package/docs/00-project/roadmap.md +89 -0
  9. package/docs/01-architecture/DSH_Environment_Service_Memory_Skill_Brainstorm.md +493 -0
  10. package/docs/01-architecture/api-verification.md +416 -0
  11. package/docs/01-architecture/architecture-overview.md +222 -0
  12. package/docs/01-architecture/data-model.md +930 -0
  13. package/docs/01-architecture/decisions/ADR-0001-plugin-as-bundle.md +29 -0
  14. package/docs/01-architecture/decisions/ADR-0002-file-based-storage.md +25 -0
  15. package/docs/01-architecture/decisions/ADR-0003-skill-router-over-search.md +25 -0
  16. package/docs/01-architecture/decisions/ADR-0004-typescript-host-js-client.md +31 -0
  17. package/docs/01-architecture/decisions/ADR-0005-layered-rule-resolution.md +36 -0
  18. package/docs/01-architecture/decisions/ADR-0006-credentials-as-references.md +30 -0
  19. package/docs/01-architecture/decisions/ADR-0007-session-scoped-default-environment.md +28 -0
  20. package/docs/01-architecture/decisions/ADR-0008-memory-bridge-not-second-store.md +31 -0
  21. package/docs/01-architecture/decisions/ADR-0009-client-host-http-transport.md +87 -0
  22. package/docs/01-architecture/decisions/ADR-0010-environment-plane-model.md +87 -0
  23. package/docs/01-architecture/decisions/ADR-0011-k8s-node-execution-model.md +92 -0
  24. package/docs/01-architecture/design.md +666 -0
  25. package/docs/01-architecture/detailed-design.md +961 -0
  26. package/docs/01-architecture/implementation-plan.md +323 -0
  27. package/docs/01-architecture/module-boundaries.md +306 -0
  28. package/docs/01-architecture/security-model.md +227 -0
  29. package/docs/01-architecture/storage-contract.md +224 -0
  30. package/docs/01-architecture/tool-contract.md +438 -0
  31. package/docs/01-architecture/ui-design.md +587 -0
  32. package/docs/02-harness/agent-behavior.md +36 -0
  33. package/docs/02-harness/change-snapshot-policy.md +29 -0
  34. package/docs/02-harness/client-ui-integration.md +110 -0
  35. package/docs/02-harness/context-policy.md +43 -0
  36. package/docs/02-harness/harness-standard.md +91 -0
  37. package/docs/02-harness/task-execution-policy.md +26 -0
  38. package/docs/02-harness/verification-policy.md +97 -0
  39. package/docs/03-openspec/archive-rule.md +25 -0
  40. package/docs/03-openspec/bugfix-rule.md +30 -0
  41. package/docs/03-openspec/design-rule.md +33 -0
  42. package/docs/03-openspec/openspec-usage-guide.md +31 -0
  43. package/docs/03-openspec/proposal-rule.md +70 -0
  44. package/docs/03-openspec/spec-rule.md +33 -0
  45. package/docs/03-openspec/tasks-rule.md +31 -0
  46. package/docs/04-development/coding-style.md +67 -0
  47. package/docs/04-development/dependency-policy.md +43 -0
  48. package/docs/04-development/development-guide.md +85 -0
  49. package/docs/04-development/directory-convention.md +105 -0
  50. package/docs/04-development/local-run-guide.md +61 -0
  51. package/docs/04-development/testing-guide.md +102 -0
  52. package/docs/05-domain/deployment-template.md +76 -0
  53. package/docs/05-domain/environment-template.md +165 -0
  54. package/docs/05-domain/operation-binding-template.md +55 -0
  55. package/docs/05-domain/operation-record-template.md +55 -0
  56. package/docs/05-domain/prompt-template.md +90 -0
  57. package/docs/05-domain/rule-template.md +73 -0
  58. package/docs/05-domain/service-template.md +39 -0
  59. package/docs/06-operations/deployment-guide.md +54 -0
  60. package/docs/06-operations/release.md +198 -0
  61. package/docs/06-operations/security-policy.md +53 -0
  62. package/docs/06-operations/troubleshooting.md +141 -0
  63. package/docs/07-templates/adr-template.md +21 -0
  64. package/docs/07-templates/bugfix-template.md +11 -0
  65. package/docs/07-templates/case-template.md +15 -0
  66. package/docs/07-templates/design-template.md +29 -0
  67. package/docs/07-templates/proposal-template.md +19 -0
  68. package/docs/07-templates/spec-template.md +15 -0
  69. package/docs/07-templates/tasks-template.md +12 -0
  70. package/docs/99-archive/README.md +13 -0
  71. package/docs/README.md +142 -0
  72. package/icon.svg +4 -0
  73. package/index.js +31 -0
  74. package/lib/app/app.d.ts +67 -0
  75. package/lib/app/app.js +494 -0
  76. package/lib/app/app.js.map +1 -0
  77. package/lib/config.d.ts +55 -0
  78. package/lib/config.js +42 -0
  79. package/lib/config.js.map +1 -0
  80. package/lib/domain/constants.d.ts +21 -0
  81. package/lib/domain/constants.js +59 -0
  82. package/lib/domain/constants.js.map +1 -0
  83. package/lib/domain/errors.d.ts +20 -0
  84. package/lib/domain/errors.js +22 -0
  85. package/lib/domain/errors.js.map +1 -0
  86. package/lib/domain/schemas.d.ts +28 -0
  87. package/lib/domain/schemas.js +445 -0
  88. package/lib/domain/schemas.js.map +1 -0
  89. package/lib/domain/types.d.ts +412 -0
  90. package/lib/domain/types.js +2 -0
  91. package/lib/domain/types.js.map +1 -0
  92. package/lib/index.d.ts +18 -0
  93. package/lib/index.js +89 -0
  94. package/lib/index.js.map +1 -0
  95. package/lib/logger.d.ts +8 -0
  96. package/lib/logger.js +13 -0
  97. package/lib/logger.js.map +1 -0
  98. package/lib/memory/bridge.d.ts +18 -0
  99. package/lib/memory/bridge.js +13 -0
  100. package/lib/memory/bridge.js.map +1 -0
  101. package/lib/registry/integrity.d.ts +10 -0
  102. package/lib/registry/integrity.js +204 -0
  103. package/lib/registry/integrity.js.map +1 -0
  104. package/lib/registry/registry.d.ts +14 -0
  105. package/lib/registry/registry.js +182 -0
  106. package/lib/registry/registry.js.map +1 -0
  107. package/lib/resolver/merge.d.ts +23 -0
  108. package/lib/resolver/merge.js +90 -0
  109. package/lib/resolver/merge.js.map +1 -0
  110. package/lib/resolver/resolve.d.ts +18 -0
  111. package/lib/resolver/resolve.js +288 -0
  112. package/lib/resolver/resolve.js.map +1 -0
  113. package/lib/resolver/template.d.ts +10 -0
  114. package/lib/resolver/template.js +42 -0
  115. package/lib/resolver/template.js.map +1 -0
  116. package/lib/router/params.d.ts +3 -0
  117. package/lib/router/params.js +83 -0
  118. package/lib/router/params.js.map +1 -0
  119. package/lib/router/router.d.ts +11 -0
  120. package/lib/router/router.js +204 -0
  121. package/lib/router/router.js.map +1 -0
  122. package/lib/session/session.d.ts +16 -0
  123. package/lib/session/session.js +64 -0
  124. package/lib/session/session.js.map +1 -0
  125. package/lib/skill.d.ts +17 -0
  126. package/lib/skill.js +56 -0
  127. package/lib/skill.js.map +1 -0
  128. package/lib/storage/atomic.d.ts +10 -0
  129. package/lib/storage/atomic.js +107 -0
  130. package/lib/storage/atomic.js.map +1 -0
  131. package/lib/storage/paths.d.ts +10 -0
  132. package/lib/storage/paths.js +50 -0
  133. package/lib/storage/paths.js.map +1 -0
  134. package/lib/storage/records.d.ts +16 -0
  135. package/lib/storage/records.js +112 -0
  136. package/lib/storage/records.js.map +1 -0
  137. package/lib/storage/sessions.d.ts +17 -0
  138. package/lib/storage/sessions.js +65 -0
  139. package/lib/storage/sessions.js.map +1 -0
  140. package/lib/tools/tools.d.ts +14 -0
  141. package/lib/tools/tools.js +472 -0
  142. package/lib/tools/tools.js.map +1 -0
  143. package/lib/transport/http.d.ts +3 -0
  144. package/lib/transport/http.js +217 -0
  145. package/lib/transport/http.js.map +1 -0
  146. package/locale/en.json +6 -0
  147. package/locale/zh.json +6 -0
  148. package/package.json +101 -6
  149. package/scripts/repair-profile.mjs +141 -0
@@ -0,0 +1,412 @@
1
+ export type RecordKind = 'environment' | 'service' | 'deployment' | 'ruleProfile' | 'operationBinding';
2
+ export type RuntimeMode = 'native' | 'docker' | 'kubernetes';
3
+ export type EnvironmentCategory = 'dev' | 'test' | 'staging' | 'production' | 'custom';
4
+ export type Status = 'configured-not-verified' | 'partially-verified' | 'verified';
5
+ export type Severity = 'info' | 'warning' | 'error';
6
+ export type MatchLevel = 'deployment' | 'environment-service' | 'service' | 'category-mode' | 'global';
7
+ export type Actor = 'agent' | 'ui';
8
+ export interface Diagnostic {
9
+ code: string;
10
+ severity: Severity;
11
+ message: string;
12
+ file?: string;
13
+ path?: string;
14
+ details?: Record<string, unknown>;
15
+ }
16
+ export interface RecordMeta {
17
+ id: string;
18
+ schemaVersion: 1;
19
+ createdAt: string;
20
+ updatedAt: string;
21
+ }
22
+ export interface LogicalRole {
23
+ id: string;
24
+ name: string;
25
+ description?: string;
26
+ }
27
+ export type HostKind = 'vm' | 'physical' | 'k8s-all-in-one' | 'k8s-worker' | 'pod-host';
28
+ export type HostAccessMethod = 'ssh' | 'kubectl' | 'docker';
29
+ export type ClusterTopology = 'all-in-one' | 'separate' | 'external';
30
+ export interface Host {
31
+ id: string;
32
+ name: string;
33
+ kind?: HostKind;
34
+ os?: string;
35
+ platform?: string;
36
+ ip?: string;
37
+ publicIp?: string;
38
+ sshPort?: number;
39
+ roles: string[];
40
+ access?: HostAccessMethod[];
41
+ clusterRef?: string;
42
+ adminUser?: string;
43
+ isActive?: boolean;
44
+ credentialRef?: string;
45
+ accounts?: HostAccount[];
46
+ note?: string;
47
+ }
48
+ export type LoginProtocol = 'ssh' | 'rdp' | 'web' | 'k8s-api' | 'docker' | 'custom';
49
+ export type LoginAuthType = 'password' | 'private-key' | 'agent' | 'token' | 'other';
50
+ export interface HostAccount {
51
+ id: string;
52
+ username: string;
53
+ purpose?: string;
54
+ protocol?: LoginProtocol;
55
+ loginUrl?: string;
56
+ port?: number;
57
+ authType?: LoginAuthType;
58
+ credentialRef?: string;
59
+ lastLoginAt?: string;
60
+ lastLoginFrom?: string;
61
+ note?: string;
62
+ }
63
+ export type LoginResult = 'success' | 'failure';
64
+ export interface LoginRecord {
65
+ id: string;
66
+ at: string;
67
+ username: string;
68
+ hostRef?: string;
69
+ accountId?: string;
70
+ protocol?: LoginProtocol;
71
+ sourceIp?: string;
72
+ result: LoginResult;
73
+ note?: string;
74
+ }
75
+ export interface Cluster {
76
+ id: string;
77
+ name: string;
78
+ kind: 'kubernetes' | 'docker';
79
+ topology?: ClusterTopology;
80
+ apiEndpoint?: string;
81
+ namespaces?: string[];
82
+ credentialRef?: string;
83
+ note?: string;
84
+ }
85
+ export interface AccessEndpoint {
86
+ id: string;
87
+ kind: 'ssh' | 'web' | 'k8s-api' | 'docker' | 'custom';
88
+ hostRef?: string;
89
+ clusterRef?: string;
90
+ url?: string;
91
+ port?: number;
92
+ credentialRef?: string;
93
+ note?: string;
94
+ }
95
+ export interface LogSourceFile {
96
+ kind: 'file';
97
+ path: string;
98
+ }
99
+ export interface LogSourceContainer {
100
+ kind: 'container-stdout';
101
+ container: string;
102
+ }
103
+ export interface LogSourcePod {
104
+ kind: 'pod-logs';
105
+ namespace: string;
106
+ workload: string;
107
+ }
108
+ export type LogSource = LogSourceFile | LogSourceContainer | LogSourcePod;
109
+ export interface ClassLocation {
110
+ kind: 'build-output' | 'deployed-dir' | 'jar-entry';
111
+ path: string;
112
+ entryPrefix?: string;
113
+ }
114
+ export interface RuleOverride {
115
+ variables?: Record<string, string | number | boolean>;
116
+ paths?: Record<string, string>;
117
+ logSources?: Partial<Record<RuntimeMode, LogSource>>;
118
+ classLocations?: Partial<Record<RuntimeMode, ClassLocation>>;
119
+ }
120
+ export interface Environment extends RecordMeta {
121
+ name: string;
122
+ aliases: string[];
123
+ category: EnvironmentCategory;
124
+ description?: string;
125
+ roles: LogicalRole[];
126
+ hosts: Host[];
127
+ clusters: Cluster[];
128
+ endpoints: AccessEndpoint[];
129
+ loginRecords?: LoginRecord[];
130
+ ruleOverrides?: RuleOverride;
131
+ }
132
+ export interface GitInfo {
133
+ url: string;
134
+ defaultBranch: string;
135
+ modulePath?: string;
136
+ }
137
+ export interface BuildInfo {
138
+ tool: 'maven' | 'gradle' | 'npm' | 'custom';
139
+ command?: string;
140
+ }
141
+ export interface ArtifactInfo {
142
+ name: string;
143
+ path?: string;
144
+ }
145
+ export interface Service extends RecordMeta {
146
+ name: string;
147
+ aliases: string[];
148
+ category: string;
149
+ description?: string;
150
+ git: GitInfo;
151
+ build?: BuildInfo;
152
+ artifact?: ArtifactInfo;
153
+ deployModes: RuntimeMode[];
154
+ ruleProfileRefs: string[];
155
+ }
156
+ export interface NativeLocation {
157
+ kind: 'native';
158
+ hostRef: string;
159
+ installDir?: string;
160
+ serviceName?: string;
161
+ processMatch?: string;
162
+ }
163
+ export interface DockerLocation {
164
+ kind: 'docker';
165
+ hostRef: string;
166
+ containerName?: string;
167
+ image?: string;
168
+ volumes?: string[];
169
+ }
170
+ export interface KubernetesLocation {
171
+ kind: 'kubernetes';
172
+ clusterRef: string;
173
+ namespace: string;
174
+ workload: {
175
+ kind: 'Deployment' | 'StatefulSet' | 'DaemonSet' | 'CronJob' | 'Pod';
176
+ name: string;
177
+ };
178
+ container?: string;
179
+ }
180
+ export type DeploymentLocation = NativeLocation | DockerLocation | KubernetesLocation;
181
+ export interface Deployment extends RecordMeta {
182
+ name?: string;
183
+ environmentId: string;
184
+ serviceId: string;
185
+ runtimeMode: RuntimeMode;
186
+ location: DeploymentLocation;
187
+ variables?: Record<string, string | number | boolean>;
188
+ ruleOverrides?: RuleOverride;
189
+ }
190
+ export interface RuleProfile extends RecordMeta {
191
+ name?: string;
192
+ description?: string;
193
+ variables?: Record<string, string | number | boolean>;
194
+ paths?: Record<string, string>;
195
+ logSources?: Partial<Record<RuntimeMode, LogSource>>;
196
+ classLocations?: Partial<Record<RuntimeMode, ClassLocation>>;
197
+ }
198
+ export interface SkillReference {
199
+ name: string;
200
+ expectedSource?: string | null;
201
+ expectedProvider?: string | null;
202
+ }
203
+ export interface OperationMatch {
204
+ environmentId?: string;
205
+ serviceId?: string;
206
+ deploymentId?: string;
207
+ deploymentMode?: RuntimeMode;
208
+ serviceCategory?: string;
209
+ }
210
+ export interface OperationPolicy {
211
+ requiresApproval: boolean;
212
+ allowProduction: boolean;
213
+ }
214
+ export interface OperationBinding extends RecordMeta {
215
+ operation: string;
216
+ match: OperationMatch;
217
+ skill: SkillReference;
218
+ parameters?: Record<string, string | number | boolean>;
219
+ policy: OperationPolicy;
220
+ enabled: boolean;
221
+ }
222
+ export type AnyRecord = Environment | Service | Deployment | RuleProfile | OperationBinding;
223
+ export type RecordByKind = {
224
+ environment: Environment;
225
+ service: Service;
226
+ deployment: Deployment;
227
+ ruleProfile: RuleProfile;
228
+ operationBinding: OperationBinding;
229
+ };
230
+ export type RuleLayer = 'global' | 'service' | 'environment' | 'deployment';
231
+ export interface RuleSource {
232
+ layer: RuleLayer;
233
+ ruleProfileId?: string;
234
+ recordId?: string;
235
+ }
236
+ export interface ProvenanceInput {
237
+ name: string;
238
+ source: RuleSource;
239
+ }
240
+ export interface ProvenanceEntry {
241
+ field: string;
242
+ definedBy: RuleSource;
243
+ inputs: ProvenanceInput[];
244
+ shadowed: RuleSource[];
245
+ value: string | number | boolean;
246
+ }
247
+ export interface ResolvedField<T> {
248
+ value: T;
249
+ provenance: ProvenanceEntry;
250
+ }
251
+ export interface ResolvedStructured<T> {
252
+ value: T;
253
+ provenance: ProvenanceEntry[];
254
+ }
255
+ export interface CredentialStatus {
256
+ ref: string;
257
+ configured: boolean;
258
+ source?: string;
259
+ }
260
+ export interface ServiceContext {
261
+ environmentId: string;
262
+ environmentName: string;
263
+ environmentCategory: EnvironmentCategory;
264
+ serviceId: string;
265
+ serviceName: string;
266
+ serviceCategory: string;
267
+ deploymentId: string;
268
+ deploymentName?: string;
269
+ runtimeMode: RuntimeMode;
270
+ source: {
271
+ gitUrl?: string;
272
+ defaultBranch?: string;
273
+ modulePath?: string;
274
+ };
275
+ artifact?: {
276
+ name: string;
277
+ path?: string;
278
+ };
279
+ location: DeploymentLocation;
280
+ variables: Record<string, ResolvedField<string | number | boolean>>;
281
+ paths: Record<string, ResolvedField<string>>;
282
+ logSource?: ResolvedStructured<LogSource>;
283
+ classLocation?: ResolvedStructured<ClassLocation>;
284
+ ruleProfiles: string[];
285
+ status: Status;
286
+ credentials: CredentialStatus[];
287
+ diagnostics: Diagnostic[];
288
+ }
289
+ export interface ResolvedSkillReference {
290
+ name: string;
291
+ source?: string | null;
292
+ provider?: string | null;
293
+ available: boolean | 'unknown';
294
+ }
295
+ export interface OperationResolution {
296
+ ok: boolean;
297
+ operation: string;
298
+ requested: {
299
+ environmentId: string;
300
+ serviceId?: string;
301
+ deploymentId?: string;
302
+ };
303
+ matchedBindingId?: string;
304
+ matchLevel?: MatchLevel;
305
+ skill?: ResolvedSkillReference;
306
+ parameters?: Record<string, string>;
307
+ policy?: OperationPolicy;
308
+ diagnostics: Diagnostic[];
309
+ }
310
+ export interface SessionContext {
311
+ sessionId: string;
312
+ defaultEnvironmentId: string | null;
313
+ persisted: boolean;
314
+ }
315
+ export interface RecordSummary {
316
+ kind: RecordKind;
317
+ id: string;
318
+ name: string;
319
+ summary?: string;
320
+ }
321
+ export interface ListResult {
322
+ items: RecordSummary[];
323
+ warnings: Diagnostic[];
324
+ }
325
+ export interface GetResult {
326
+ record: AnyRecord;
327
+ yaml: string;
328
+ }
329
+ export interface FindHit {
330
+ kind: RecordKind;
331
+ id: string;
332
+ name: string;
333
+ field: 'id' | 'name' | 'alias' | 'category';
334
+ }
335
+ export interface FindResult {
336
+ hits: FindHit[];
337
+ }
338
+ export interface SaveResult {
339
+ id: string;
340
+ kind: RecordKind;
341
+ created: boolean;
342
+ dryRun: boolean;
343
+ warnings: Diagnostic[];
344
+ }
345
+ export interface RemoveResult {
346
+ id: string;
347
+ kind: RecordKind;
348
+ deleted: boolean;
349
+ blockers: Diagnostic[];
350
+ }
351
+ export interface ValidationReport {
352
+ ok: boolean;
353
+ counts: Record<string, number>;
354
+ diagnostics: Diagnostic[];
355
+ }
356
+ export interface MetaResult {
357
+ dataDir: string;
358
+ version: string;
359
+ counts: Record<string, number>;
360
+ warnings: Diagnostic[];
361
+ }
362
+ export interface SaveOptions {
363
+ dryRun?: boolean;
364
+ }
365
+ export interface RemoveOptions {
366
+ dryRun?: boolean;
367
+ }
368
+ export interface ResolveRequest {
369
+ environmentId: string;
370
+ serviceId: string;
371
+ deploymentId?: string;
372
+ }
373
+ export interface RouteRequest {
374
+ operation: string;
375
+ environmentId: string;
376
+ serviceId?: string;
377
+ deploymentId?: string;
378
+ }
379
+ export interface SkillSummary {
380
+ name: string;
381
+ description?: string;
382
+ whenToUse?: string;
383
+ source?: string;
384
+ provider?: string;
385
+ }
386
+ export interface SkillSnapshot {
387
+ skills: SkillSummary[];
388
+ complete: boolean;
389
+ }
390
+ export interface SkillDirectory {
391
+ snapshot(options?: {
392
+ signal?: AbortSignal;
393
+ }): Promise<SkillSnapshot>;
394
+ }
395
+ export interface CredentialDirectory {
396
+ describe(ref: string): Promise<{
397
+ configured: boolean;
398
+ source?: string;
399
+ }>;
400
+ set(ref: string, value: string): Promise<void>;
401
+ unset(ref: string): Promise<void>;
402
+ }
403
+ export interface RegistrySnapshot {
404
+ environments: Map<string, Environment>;
405
+ services: Map<string, Service>;
406
+ deployments: Map<string, Deployment>;
407
+ ruleProfiles: Map<string, RuleProfile>;
408
+ operationBindings: Map<string, OperationBinding>;
409
+ byAlias: Map<string, string>;
410
+ diagnostics: Diagnostic[];
411
+ loadedAt: string;
412
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/domain/types.ts"],"names":[],"mappings":""}
package/lib/index.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { Config } from './config.js';
2
+ export declare const name = "dsh-env-manager";
3
+ export declare const inject: string[];
4
+ export { Config };
5
+ export interface ApplyConfig {
6
+ dataDir?: string;
7
+ maxRecords?: number;
8
+ registerSkill?: boolean;
9
+ writePolicy?: {
10
+ allowUiProductionWrites?: boolean;
11
+ requireApprovalForDelete?: boolean;
12
+ requireApprovalForProductionSave?: boolean;
13
+ };
14
+ defaults?: {
15
+ environmentId?: string;
16
+ };
17
+ }
18
+ export declare function apply(ctx: any, config?: ApplyConfig): void;
package/lib/index.js ADDED
@@ -0,0 +1,89 @@
1
+ import os from 'node:os';
2
+ import { App } from './app/app.js';
3
+ import { Config, normalizeConfig } from './config.js';
4
+ import { consoleLogger } from './logger.js';
5
+ import { resolveDataDir } from './storage/paths.js';
6
+ import { cleanupTempFiles } from './storage/atomic.js';
7
+ import { createEnvironmentManagerSkill } from './skill.js';
8
+ import { createToolDefinitions } from './tools/tools.js';
9
+ import { registerHttpTransport } from './transport/http.js';
10
+ export const name = 'dsh-env-manager';
11
+ export const inject = ['tools'];
12
+ export { Config };
13
+ export function apply(ctx, config = {}) {
14
+ const normalized = normalizeConfig(config);
15
+ const profileContext = ctx.get('profileContext');
16
+ const profileDir = profileContext?.dir ?? process.env.DSH_PROFILE_DIR ?? process.cwd();
17
+ const dataDir = resolveDataDir(normalized.dataDir, profileDir, process.cwd(), os.homedir());
18
+ const skills = ctx.get('skills');
19
+ const credentials = ctx.get('credentials');
20
+ const app = new App({
21
+ dataDir,
22
+ maxRecords: normalized.maxRecords,
23
+ writePolicy: {
24
+ allowUiProductionWrites: normalized.writePolicy.allowUiProductionWrites,
25
+ },
26
+ skills: skills
27
+ ? {
28
+ snapshot: (options) => skills.snapshot(options),
29
+ }
30
+ : null,
31
+ credentials: credentials
32
+ ? {
33
+ async describe(ref) {
34
+ const info = await credentials.describe(ref);
35
+ return { configured: info.configured, source: info.source };
36
+ },
37
+ async set(ref, value) {
38
+ if (typeof credentials.set !== 'function') {
39
+ throw new Error('the credential service is not writable');
40
+ }
41
+ await credentials.set(ref, value);
42
+ },
43
+ async unset(ref) {
44
+ if (typeof credentials.unset !== 'function') {
45
+ throw new Error('the credential service is not writable');
46
+ }
47
+ await credentials.unset(ref);
48
+ },
49
+ }
50
+ : null,
51
+ logger: consoleLogger,
52
+ defaults: normalized.defaults,
53
+ });
54
+ void app.init().catch((error) => {
55
+ consoleLogger.error(`Could not initialize ${dataDir}: ${error instanceof Error ? error.message : String(error)}`);
56
+ });
57
+ void cleanupTempFiles(dataDir).catch(() => undefined);
58
+ const disposeTools = [];
59
+ ctx.effect(() => {
60
+ const definitions = createToolDefinitions({
61
+ ctx,
62
+ app,
63
+ defaults: normalized.defaults,
64
+ writePolicy: normalized.writePolicy,
65
+ });
66
+ for (const definition of definitions) {
67
+ disposeTools.push(ctx.tools.register(definition));
68
+ }
69
+ const disposeHttp = registerHttpTransport(ctx, app, consoleLogger);
70
+ let disposeSkill;
71
+ if (normalized.registerSkill && skills && typeof skills.register === 'function') {
72
+ try {
73
+ disposeSkill = skills.register(createEnvironmentManagerSkill());
74
+ consoleLogger.debug('Registered discovery skill dsh-env-manager');
75
+ }
76
+ catch (error) {
77
+ consoleLogger.warn(`Could not register discovery skill: ${error instanceof Error ? error.message : String(error)}`);
78
+ }
79
+ }
80
+ return () => {
81
+ disposeSkill?.();
82
+ for (const dispose of disposeTools.splice(0))
83
+ dispose();
84
+ disposeHttp();
85
+ };
86
+ });
87
+ consoleLogger.info(`Environment registry ready at ${dataDir}`);
88
+ }
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,MAAM,CAAC,MAAM,IAAI,GAAG,iBAAiB,CAAA;AAErC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,CAAA;AAE/B,OAAO,EAAE,MAAM,EAAE,CAAA;AAcjB,MAAM,UAAU,KAAK,CAAC,GAAQ,EAAE,SAAsB,EAAE;IACtD,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;IAC1C,MAAM,cAAc,GAAG,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAiC,CAAA;IAChF,MAAM,UAAU,GACd,cAAc,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACrE,MAAM,OAAO,GAAG,cAAc,CAC5B,UAAU,CAAC,OAAO,EAClB,UAAU,EACV,OAAO,CAAC,GAAG,EAAE,EACb,EAAE,CAAC,OAAO,EAAE,CACb,CAAA;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAChC,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAE1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC;QAClB,OAAO;QACP,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,WAAW,EAAE;YACX,uBAAuB,EAAE,UAAU,CAAC,WAAW,CAAC,uBAAuB;SACxE;QACD,MAAM,EAAE,MAAM;YACZ,CAAC,CAAC;gBACE,QAAQ,EAAE,CAAC,OAAkC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;aAC3E;YACH,CAAC,CAAC,IAAI;QACR,WAAW,EAAE,WAAW;YACtB,CAAC,CAAC;gBACE,KAAK,CAAC,QAAQ,CAAC,GAAW;oBACxB,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;oBAC5C,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAA;gBAC7D,CAAC;gBACD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;oBAClC,IAAI,OAAO,WAAW,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;wBAC1C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;oBAC3D,CAAC;oBACD,MAAM,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;gBACnC,CAAC;gBACD,KAAK,CAAC,KAAK,CAAC,GAAW;oBACrB,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;wBAC5C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;oBAC3D,CAAC;oBACD,MAAM,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;gBAC9B,CAAC;aACF;YACH,CAAC,CAAC,IAAI;QACR,MAAM,EAAE,aAAa;QACrB,QAAQ,EAAE,UAAU,CAAC,QAAQ;KAC9B,CAAC,CAAA;IAEF,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9B,aAAa,CAAC,KAAK,CACjB,wBAAwB,OAAO,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAA;IACH,CAAC,CAAC,CAAA;IACF,KAAK,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;IAErD,MAAM,YAAY,GAAsB,EAAE,CAAA;IAE1C,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;QACd,MAAM,WAAW,GAAG,qBAAqB,CAAC;YACxC,GAAG;YACH,GAAG;YACH,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,WAAW,EAAE,UAAU,CAAC,WAAW;SACpC,CAAC,CAAA;QACF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAA;QACnD,CAAC;QACD,MAAM,WAAW,GAAG,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,CAAA;QAElE,IAAI,YAAsC,CAAA;QAC1C,IAAI,UAAU,CAAC,aAAa,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YAChF,IAAI,CAAC;gBACH,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,6BAA6B,EAAE,CAAC,CAAA;gBAC/D,aAAa,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAA;YACnE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,aAAa,CAAC,IAAI,CAChB,uCAAuC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAChG,CAAA;YACH,CAAC;QACH,CAAC;QAED,OAAO,GAAG,EAAE;YACV,YAAY,EAAE,EAAE,CAAA;YAChB,KAAK,MAAM,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;gBAAE,OAAO,EAAE,CAAA;YACvD,WAAW,EAAE,CAAA;QACf,CAAC,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,aAAa,CAAC,IAAI,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAA;AAChE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface Logger {
2
+ debug(message: string, details?: unknown): void;
3
+ info(message: string, details?: unknown): void;
4
+ warn(message: string, details?: unknown): void;
5
+ error(message: string, details?: unknown): void;
6
+ }
7
+ export declare const consoleLogger: Logger;
8
+ export declare const silentLogger: Logger;
package/lib/logger.js ADDED
@@ -0,0 +1,13 @@
1
+ export const consoleLogger = {
2
+ debug: (message, details) => console.debug(`[dsh-env-manager] ${message}`, details ?? ''),
3
+ info: (message, details) => console.info(`[dsh-env-manager] ${message}`, details ?? ''),
4
+ warn: (message, details) => console.warn(`[dsh-env-manager] ${message}`, details ?? ''),
5
+ error: (message, details) => console.error(`[dsh-env-manager] ${message}`, details ?? ''),
6
+ };
7
+ export const silentLogger = {
8
+ debug: () => undefined,
9
+ info: () => undefined,
10
+ warn: () => undefined,
11
+ error: () => undefined,
12
+ };
13
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC;IACzF,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC;IACvF,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC;IACvF,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC;CAC1F,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS;IACtB,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;IACrB,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;IACrB,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS;CACvB,CAAA"}
@@ -0,0 +1,18 @@
1
+ import type { OperationResolution } from '../domain/types.js';
2
+ export interface OperationRecordDraft {
3
+ operation: string;
4
+ resolution: OperationResolution;
5
+ outcome: 'planned' | 'succeeded' | 'failed' | 'rejected';
6
+ evidence?: string[];
7
+ }
8
+ /**
9
+ * Optional memory integration. V1 never requires the memory plugin: the null
10
+ * bridge reports unavailability and never writes.
11
+ */
12
+ export interface MemoryBridge {
13
+ readonly available: boolean;
14
+ emit(record: OperationRecordDraft): Promise<void>;
15
+ query(): Promise<never[]>;
16
+ propose(): Promise<never>;
17
+ }
18
+ export declare const nullMemoryBridge: MemoryBridge;
@@ -0,0 +1,13 @@
1
+ export const nullMemoryBridge = {
2
+ available: false,
3
+ async emit() {
4
+ return undefined;
5
+ },
6
+ async query() {
7
+ return [];
8
+ },
9
+ async propose() {
10
+ throw new Error('Memory bridge is not configured');
11
+ },
12
+ };
13
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/memory/bridge.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,SAAS,EAAE,KAAK;IAChB,KAAK,CAAC,IAAI;QACR,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACpD,CAAC;CACF,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { Diagnostic, RecordKind, RegistrySnapshot } from '../domain/types.js';
2
+ /** Referential checks over a loaded snapshot. Broken references are diagnostics. */
3
+ export declare function checkIntegrity(snapshot: RegistrySnapshot): Diagnostic[];
4
+ export interface Referrer {
5
+ kind: RecordKind;
6
+ id: string;
7
+ field: string;
8
+ }
9
+ /** Records that point at `kind/id`, used to block a delete. */
10
+ export declare function findReferences(snapshot: RegistrySnapshot, kind: RecordKind, id: string): Referrer[];