@pellux/goodvibes-sdk 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/artifacts/operator-contract.json +26 -2
- package/dist/platform/companion/companion-chat-manager.d.ts +6 -12
- package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-manager.js +8 -2
- package/dist/platform/config/index.d.ts +2 -1
- package/dist/platform/config/index.d.ts.map +1 -1
- package/dist/platform/config/index.js +1 -0
- package/dist/platform/config/manager.d.ts +35 -0
- package/dist/platform/config/manager.d.ts.map +1 -1
- package/dist/platform/config/manager.js +98 -2
- package/dist/platform/config/shared-config-tier.d.ts +51 -0
- package/dist/platform/config/shared-config-tier.d.ts.map +1 -0
- package/dist/platform/config/shared-config-tier.js +127 -0
- package/dist/platform/control-plane/operator-contract-schemas-knowledge.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-knowledge.js +6 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.js +2 -1
- package/dist/platform/daemon/facade-composition.d.ts.map +1 -1
- package/dist/platform/daemon/facade-composition.js +1 -0
- package/dist/platform/daemon/homeassistant-chat.d.ts +4 -1
- package/dist/platform/daemon/homeassistant-chat.d.ts.map +1 -1
- package/dist/platform/daemon/homeassistant-chat.js +1 -1
- package/dist/platform/daemon/http/homeassistant-routes.d.ts.map +1 -1
- package/dist/platform/daemon/http/homeassistant-routes.js +28 -2
- package/dist/platform/integrations/webhooks.d.ts +15 -0
- package/dist/platform/integrations/webhooks.d.ts.map +1 -1
- package/dist/platform/integrations/webhooks.js +18 -0
- package/dist/platform/knowledge/extraction-policy.d.ts +12 -1
- package/dist/platform/knowledge/extraction-policy.d.ts.map +1 -1
- package/dist/platform/knowledge/extraction-policy.js +19 -1
- package/dist/platform/knowledge/graphql-schema.d.ts +1 -1
- package/dist/platform/knowledge/graphql-schema.d.ts.map +1 -1
- package/dist/platform/knowledge/graphql-schema.js +5 -0
- package/dist/platform/knowledge/home-graph/index.d.ts.map +1 -1
- package/dist/platform/knowledge/home-graph/index.js +4 -0
- package/dist/platform/knowledge/home-graph/link.d.ts +2 -2
- package/dist/platform/knowledge/home-graph/link.d.ts.map +1 -1
- package/dist/platform/knowledge/home-graph/link.js +60 -9
- package/dist/platform/knowledge/home-graph/refinement.d.ts +14 -9
- package/dist/platform/knowledge/home-graph/refinement.d.ts.map +1 -1
- package/dist/platform/knowledge/home-graph/refinement.js +18 -3
- package/dist/platform/knowledge/home-graph/reset.js +21 -4
- package/dist/platform/knowledge/home-graph/service.d.ts +10 -11
- package/dist/platform/knowledge/home-graph/service.d.ts.map +1 -1
- package/dist/platform/knowledge/home-graph/triage.d.ts +103 -0
- package/dist/platform/knowledge/home-graph/triage.d.ts.map +1 -0
- package/dist/platform/knowledge/home-graph/triage.js +362 -0
- package/dist/platform/knowledge/home-graph/types.d.ts +15 -0
- package/dist/platform/knowledge/home-graph/types.d.ts.map +1 -1
- package/dist/platform/knowledge/knowledge-api.d.ts +6 -0
- package/dist/platform/knowledge/knowledge-api.d.ts.map +1 -1
- package/dist/platform/knowledge/knowledge-api.js +5 -0
- package/dist/platform/knowledge/knowledge-history-types.d.ts +56 -0
- package/dist/platform/knowledge/knowledge-history-types.d.ts.map +1 -0
- package/dist/platform/knowledge/knowledge-history-types.js +1 -0
- package/dist/platform/knowledge/packet.d.ts.map +1 -1
- package/dist/platform/knowledge/packet.js +27 -3
- package/dist/platform/knowledge/scope-records.js +4 -2
- package/dist/platform/knowledge/semantic/answer-gaps.d.ts +8 -0
- package/dist/platform/knowledge/semantic/answer-gaps.d.ts.map +1 -1
- package/dist/platform/knowledge/semantic/answer-gaps.js +26 -6
- package/dist/platform/knowledge/semantic/enrichment.d.ts.map +1 -1
- package/dist/platform/knowledge/semantic/enrichment.js +15 -13
- package/dist/platform/knowledge/semantic/graph-index.d.ts.map +1 -1
- package/dist/platform/knowledge/semantic/graph-index.js +3 -1
- package/dist/platform/knowledge/semantic/service.d.ts +7 -0
- package/dist/platform/knowledge/semantic/service.d.ts.map +1 -1
- package/dist/platform/knowledge/semantic/service.js +10 -1
- package/dist/platform/knowledge/service-node-admin.d.ts +46 -0
- package/dist/platform/knowledge/service-node-admin.d.ts.map +1 -0
- package/dist/platform/knowledge/service-node-admin.js +72 -0
- package/dist/platform/knowledge/service.d.ts +24 -20
- package/dist/platform/knowledge/service.d.ts.map +1 -1
- package/dist/platform/knowledge/service.js +23 -47
- package/dist/platform/knowledge/store-config.d.ts +34 -0
- package/dist/platform/knowledge/store-config.d.ts.map +1 -1
- package/dist/platform/knowledge/store-config.js +23 -0
- package/dist/platform/knowledge/store-load.d.ts +3 -1
- package/dist/platform/knowledge/store-load.d.ts.map +1 -1
- package/dist/platform/knowledge/store-load.js +3 -1
- package/dist/platform/knowledge/store-node-history.d.ts +49 -0
- package/dist/platform/knowledge/store-node-history.d.ts.map +1 -0
- package/dist/platform/knowledge/store-node-history.js +331 -0
- package/dist/platform/knowledge/store-record-delete.d.ts +25 -0
- package/dist/platform/knowledge/store-record-delete.d.ts.map +1 -0
- package/dist/platform/knowledge/store-record-delete.js +84 -0
- package/dist/platform/knowledge/store-schema.d.ts +3 -1
- package/dist/platform/knowledge/store-schema.d.ts.map +1 -1
- package/dist/platform/knowledge/store-schema.js +66 -0
- package/dist/platform/knowledge/store.d.ts +19 -1
- package/dist/platform/knowledge/store.d.ts.map +1 -1
- package/dist/platform/knowledge/store.js +69 -108
- package/dist/platform/knowledge/types.d.ts +18 -0
- package/dist/platform/knowledge/types.d.ts.map +1 -1
- package/dist/platform/providers/registry.d.ts +18 -0
- package/dist/platform/providers/registry.d.ts.map +1 -1
- package/dist/platform/providers/registry.js +49 -3
- package/dist/platform/providers/runtime-snapshot.d.ts.map +1 -1
- package/dist/platform/providers/runtime-snapshot.js +14 -2
- package/dist/platform/runtime/memory-spine/client.d.ts +12 -0
- package/dist/platform/runtime/memory-spine/client.d.ts.map +1 -1
- package/dist/platform/runtime/memory-spine/client.js +14 -4
- package/dist/platform/runtime/memory-spine/index.d.ts +1 -0
- package/dist/platform/runtime/memory-spine/index.d.ts.map +1 -1
- package/dist/platform/runtime/memory-spine/index.js +1 -0
- package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts.map +1 -1
- package/dist/platform/runtime/memory-spine/recall-snapshot.js +16 -3
- package/dist/platform/runtime/memory-spine/wire-verb-availability.d.ts +59 -0
- package/dist/platform/runtime/memory-spine/wire-verb-availability.d.ts.map +1 -0
- package/dist/platform/runtime/memory-spine/wire-verb-availability.js +114 -0
- package/dist/platform/runtime/services.d.ts.map +1 -1
- package/dist/platform/runtime/services.js +3 -12
- package/dist/platform/state/memory-recall-contract.d.ts +7 -0
- package/dist/platform/state/memory-recall-contract.d.ts.map +1 -1
- package/dist/platform/state/memory-recall-contract.js +2 -0
- package/dist/platform/utils/notify.d.ts +25 -1
- package/dist/platform/utils/notify.d.ts.map +1 -1
- package/dist/platform/utils/notify.js +29 -1
- package/dist/platform/version.js +1 -1
- package/package.json +9 -9
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"product": {
|
|
4
4
|
"id": "goodvibes",
|
|
5
5
|
"surface": "operator",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.3.0"
|
|
7
7
|
},
|
|
8
8
|
"auth": {
|
|
9
9
|
"modes": [
|
|
@@ -42121,6 +42121,21 @@
|
|
|
42121
42121
|
"estimatedTokens": {
|
|
42122
42122
|
"type": "number"
|
|
42123
42123
|
},
|
|
42124
|
+
"truncated": {
|
|
42125
|
+
"type": "boolean"
|
|
42126
|
+
},
|
|
42127
|
+
"totalCandidates": {
|
|
42128
|
+
"type": "number"
|
|
42129
|
+
},
|
|
42130
|
+
"droppedCount": {
|
|
42131
|
+
"type": "number"
|
|
42132
|
+
},
|
|
42133
|
+
"droppedForBudget": {
|
|
42134
|
+
"type": "number"
|
|
42135
|
+
},
|
|
42136
|
+
"budgetExhausted": {
|
|
42137
|
+
"type": "boolean"
|
|
42138
|
+
},
|
|
42124
42139
|
"items": {
|
|
42125
42140
|
"type": "array",
|
|
42126
42141
|
"items": {
|
|
@@ -42213,6 +42228,11 @@
|
|
|
42213
42228
|
"strategy",
|
|
42214
42229
|
"budgetLimit",
|
|
42215
42230
|
"estimatedTokens",
|
|
42231
|
+
"truncated",
|
|
42232
|
+
"totalCandidates",
|
|
42233
|
+
"droppedCount",
|
|
42234
|
+
"droppedForBudget",
|
|
42235
|
+
"budgetExhausted",
|
|
42216
42236
|
"items"
|
|
42217
42237
|
],
|
|
42218
42238
|
"additionalProperties": false
|
|
@@ -59029,6 +59049,9 @@
|
|
|
59029
59049
|
},
|
|
59030
59050
|
"totalBeforeRecallFilter": {
|
|
59031
59051
|
"type": "number"
|
|
59052
|
+
},
|
|
59053
|
+
"recallFloor": {
|
|
59054
|
+
"type": "number"
|
|
59032
59055
|
}
|
|
59033
59056
|
},
|
|
59034
59057
|
"required": [
|
|
@@ -59040,7 +59063,8 @@
|
|
|
59040
59063
|
"recallFiltered",
|
|
59041
59064
|
"excludedFlaggedCount",
|
|
59042
59065
|
"excludedBelowFloorCount",
|
|
59043
|
-
"totalBeforeRecallFilter"
|
|
59066
|
+
"totalBeforeRecallFilter",
|
|
59067
|
+
"recallFloor"
|
|
59044
59068
|
],
|
|
59045
59069
|
"additionalProperties": false
|
|
59046
59070
|
},
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* - A GC sweep closes sessions that have been idle beyond the TTL.
|
|
21
21
|
*/
|
|
22
22
|
import type { ProviderMessage } from '../providers/interface.js';
|
|
23
|
-
import type { CompanionChatMessageAttachmentInput, CompanionChatMessage, CompanionChatSession, CreateCompanionChatSessionInput, EditCompanionChatMessageInput, EditCompanionChatMessageOutput, RegenerateCompanionChatMessageInput, RegenerateCompanionChatMessageOutput, UpdateCompanionChatSessionInput } from './companion-chat-types.js';
|
|
23
|
+
import type { CompanionChatMessageAttachmentInput, CompanionChatMessage, CompanionChatSession, CompanionChatTurnEvent, CreateCompanionChatSessionInput, EditCompanionChatMessageInput, EditCompanionChatMessageOutput, RegenerateCompanionChatMessageInput, RegenerateCompanionChatMessageOutput, UpdateCompanionChatSessionInput } from './companion-chat-types.js';
|
|
24
24
|
import { type CompanionChatArtifactStore } from './companion-chat-attachments.js';
|
|
25
25
|
import type { CompanionSessionBrokerBridge } from './companion-chat-broker-bridge.js';
|
|
26
26
|
import type { CompanionChatRateLimiterOptions } from './companion-chat-rate-limiter.js';
|
|
@@ -85,13 +85,8 @@ export interface CompanionChatManagerConfig {
|
|
|
85
85
|
readonly runtimeBus?: RuntimeEventBus | null | undefined;
|
|
86
86
|
/** Optional artifact store used to resolve and inline chat attachments. */
|
|
87
87
|
readonly artifactStore?: CompanionChatArtifactStore | null | undefined;
|
|
88
|
-
/**
|
|
89
|
-
*
|
|
90
|
-
* Default: `<homeDirectory>/.goodvibes/companion-chat/sessions/` when
|
|
91
|
-
* `homeDirectory` is provided, else the OS home. Prefer passing this (or
|
|
92
|
-
* `homeDirectory`) explicitly so an isolated-home daemon never touches the
|
|
93
|
-
* real `~/.goodvibes`.
|
|
94
|
-
*/
|
|
88
|
+
/** Directory for session JSON files. Default `<homeDirectory>/.goodvibes/companion-chat/sessions/`
|
|
89
|
+
* (else OS home). Prefer passing this (or `homeDirectory`) so an isolated-home daemon stays in. */
|
|
95
90
|
readonly sessionsDir?: string | undefined;
|
|
96
91
|
/** Injected home dir; when `sessionsDir` is omitted, the persistence root is
|
|
97
92
|
* derived from THIS home (not the OS home) so an isolated-home daemon stays in. */
|
|
@@ -109,10 +104,7 @@ export interface CompanionChatManagerConfig {
|
|
|
109
104
|
/** Age (ms past closedAt) at which a CLOSED session's persisted file is PERMANENTLY
|
|
110
105
|
* deleted. Closed sessions are HISTORY: default `undefined` = retain indefinitely. */
|
|
111
106
|
readonly closedSessionRetentionMs?: number | undefined;
|
|
112
|
-
/**
|
|
113
|
-
* Pass `false` to disable disk persistence entirely (useful in tests).
|
|
114
|
-
* Default: true
|
|
115
|
-
*/
|
|
107
|
+
/** Pass `false` to disable disk persistence entirely (useful in tests). Default: true */
|
|
116
108
|
readonly persist?: boolean | undefined;
|
|
117
109
|
/** Rate-limiting options. Defaults: 30 msgs/min per client, 10/min per session. */
|
|
118
110
|
readonly rateLimiter?: CompanionChatRateLimiterOptions | false | undefined;
|
|
@@ -221,6 +213,8 @@ export declare class CompanionChatManager {
|
|
|
221
213
|
postMessageAndWaitForReply(sessionId: string, content: string, clientId?: string, options?: {
|
|
222
214
|
readonly timeoutMs?: number | undefined;
|
|
223
215
|
readonly attachments?: readonly CompanionChatMessageAttachmentInput[] | undefined;
|
|
216
|
+
/** In-process tap for this turn's incremental events; independent of the gateway SSE fan-out. */
|
|
217
|
+
readonly onTurnEvent?: ((event: CompanionChatTurnEvent) => void) | undefined;
|
|
224
218
|
}): Promise<CompanionChatReplyResult>;
|
|
225
219
|
private _postMessageInternal;
|
|
226
220
|
dispose(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"companion-chat-manager.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EACV,mCAAmC,EACnC,oBAAoB,EACpB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"companion-chat-manager.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -338,6 +338,7 @@ export class CompanionChatManager {
|
|
|
338
338
|
void this._postMessageInternal(sessionId, content, clientId, {
|
|
339
339
|
pendingReply: { resolve, timeout },
|
|
340
340
|
attachments: options.attachments,
|
|
341
|
+
...(options.onTurnEvent ? { onTurnEvent: options.onTurnEvent } : {}),
|
|
341
342
|
})
|
|
342
343
|
.then((id) => { messageId = id; })
|
|
343
344
|
.catch((error) => {
|
|
@@ -386,7 +387,7 @@ export class CompanionChatManager {
|
|
|
386
387
|
if (options.pendingReply) {
|
|
387
388
|
this.pendingReplies.set(messageId, options.pendingReply);
|
|
388
389
|
}
|
|
389
|
-
void this._runTurn(session, messageId).catch((error) => {
|
|
390
|
+
void this._runTurn(session, messageId, options.onTurnEvent).catch((error) => {
|
|
390
391
|
logger.warn('[companion-chat] turn execution failed', {
|
|
391
392
|
sessionId,
|
|
392
393
|
messageId,
|
|
@@ -409,12 +410,17 @@ export class CompanionChatManager {
|
|
|
409
410
|
// ---------------------------------------------------------------------------
|
|
410
411
|
// Turn execution
|
|
411
412
|
// ---------------------------------------------------------------------------
|
|
412
|
-
async _runTurn(session, userMessageId) {
|
|
413
|
+
async _runTurn(session, userMessageId, onTurnEvent) {
|
|
413
414
|
const turnId = randomUUID();
|
|
414
415
|
const sessionId = session.meta.id;
|
|
415
416
|
const abortSignal = session.abortController.signal;
|
|
416
417
|
const publish = (event) => {
|
|
417
418
|
this.eventPublisher.publishEvent(`companion-chat.${event.type}`, event, session.subscriberClientId ? { clientId: session.subscriberClientId } : undefined);
|
|
419
|
+
// In-process tap (e.g. the HA SSE route); a throwing listener must not break the turn.
|
|
420
|
+
try {
|
|
421
|
+
onTurnEvent?.(event);
|
|
422
|
+
}
|
|
423
|
+
catch { /* isolate listener */ }
|
|
418
424
|
};
|
|
419
425
|
// Build user-message envelope for turn.started
|
|
420
426
|
const userMsg = session.messages.find((m) => m.id === userMessageId);
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* - Pure helpers that derive values from an explicit ConfigManager instance
|
|
7
7
|
*/
|
|
8
8
|
export { ConfigManager } from './manager.js';
|
|
9
|
-
export type { DeepReadonly } from './manager.js';
|
|
9
|
+
export type { DeepReadonly, ConfigKeyTier, ConfigKeySource } from './manager.js';
|
|
10
|
+
export { SHARED_CONFIG_KEYS, isSharedConfigKey } from './shared-config-tier.js';
|
|
10
11
|
export type { GoodVibesConfig, ConfigKey, ConfigValue, ConfigSetting, PermissionMode, PermissionAction, PermissionsToolConfig, NotificationsConfig } from './schema.js';
|
|
11
12
|
export { DEFAULT_CONFIG, CONFIG_KEYS, CONFIG_SCHEMA, isValidConfigKey } from './schema.js';
|
|
12
13
|
export type { PersistedFlagState } from './schema-types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platform/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platform/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - Pure helpers that derive values from an explicit ConfigManager instance
|
|
7
7
|
*/
|
|
8
8
|
export { ConfigManager } from './manager.js';
|
|
9
|
+
export { SHARED_CONFIG_KEYS, isSharedConfigKey } from './shared-config-tier.js';
|
|
9
10
|
export { DEFAULT_CONFIG, CONFIG_KEYS, CONFIG_SCHEMA, isValidConfigKey } from './schema.js';
|
|
10
11
|
export { ConfigError } from '../types/errors.js';
|
|
11
12
|
export { migrateDangerDaemonAlias } from './migrations.js';
|
|
@@ -16,11 +16,25 @@ export type ConfigOverrides = ConfigCliOverrides & ({
|
|
|
16
16
|
configDir: string;
|
|
17
17
|
homeDir?: string | undefined;
|
|
18
18
|
sharedConfigPath?: string | undefined;
|
|
19
|
+
sharedTierPath?: string | undefined;
|
|
19
20
|
} | {
|
|
20
21
|
homeDir: string;
|
|
21
22
|
configDir?: string | undefined;
|
|
22
23
|
sharedConfigPath?: string | undefined;
|
|
24
|
+
sharedTierPath?: string | undefined;
|
|
23
25
|
});
|
|
26
|
+
/** The tier a resolved config value came from — inspectable via describeConfigKeySource. */
|
|
27
|
+
export type ConfigKeyTier = 'shared' | 'project' | 'global' | 'default';
|
|
28
|
+
/** Where a config key's live value resolves from, and whether it rides the shared tier. */
|
|
29
|
+
export interface ConfigKeySource {
|
|
30
|
+
readonly key: ConfigKey;
|
|
31
|
+
readonly value: unknown;
|
|
32
|
+
readonly tier: ConfigKeyTier;
|
|
33
|
+
/** True when this key resolves from/writes to the surface-root-independent shared tier. */
|
|
34
|
+
readonly shareable: boolean;
|
|
35
|
+
/** The shared-tier settings file path, or null when no shared tier is configured. */
|
|
36
|
+
readonly sharedTierPath: string | null;
|
|
37
|
+
}
|
|
24
38
|
export interface ConfigSetOptions {
|
|
25
39
|
bypassManagedLock?: boolean | undefined;
|
|
26
40
|
}
|
|
@@ -41,6 +55,10 @@ export declare class ConfigManager {
|
|
|
41
55
|
private readonly projectConfigPath;
|
|
42
56
|
private readonly workingDirectory;
|
|
43
57
|
private readonly homeDirectory;
|
|
58
|
+
/** Surface-root-independent shared settings file (~/.goodvibes/shared/settings.json), or null. */
|
|
59
|
+
private readonly sharedTierPath;
|
|
60
|
+
/** Shared keys whose value the last load actually sourced from the shared tier file. */
|
|
61
|
+
private readonly sharedKeysPresent;
|
|
44
62
|
private hookDispatcher;
|
|
45
63
|
private readonly _listeners;
|
|
46
64
|
constructor(overrides: ConfigOverrides);
|
|
@@ -95,6 +113,23 @@ export declare class ConfigManager {
|
|
|
95
113
|
saveProject(): void;
|
|
96
114
|
/** Load config from disk: global then project (project wins). Deep-merges with defaults. */
|
|
97
115
|
load(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Overlay any shared-tier values for the shared keys onto the resolved config.
|
|
118
|
+
* A shared key absent from the shared file is left at its surface-local value
|
|
119
|
+
* (the fallback that keeps existing setups working). Records which keys were
|
|
120
|
+
* actually sourced from the shared tier so describeConfigKeySource is honest.
|
|
121
|
+
*/
|
|
122
|
+
private loadSharedTier;
|
|
123
|
+
/** The shared-tier settings file path, or null when no shared tier is configured. */
|
|
124
|
+
getSharedTierPath(): string | null;
|
|
125
|
+
/**
|
|
126
|
+
* Report which tier a key's live value resolves from (shared / project / global
|
|
127
|
+
* / default) and whether it rides the shared tier. Reads the on-disk layers on
|
|
128
|
+
* demand so the resolution order is inspectable, not just documented.
|
|
129
|
+
*/
|
|
130
|
+
describeConfigKeySource(key: ConfigKey): ConfigKeySource;
|
|
131
|
+
/** True when the JSON settings file at `path` carries an explicit value for `key`. */
|
|
132
|
+
private fileHasKey;
|
|
98
133
|
/**
|
|
99
134
|
* Removal-of-`danger.daemon` migration (see CHANGELOG 1.0.0): rewrite an explicit legacy
|
|
100
135
|
* `danger.daemon = false` onto `daemon.enabled = false` before the raw JSON
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/platform/config/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/platform/config/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,10 +4,11 @@ import { DEFAULT_CONFIG, CONFIG_SCHEMA } from './schema.js';
|
|
|
4
4
|
import { ConfigError } from '../types/errors.js';
|
|
5
5
|
import { logger } from '../utils/logger.js';
|
|
6
6
|
import { getManagedSettingLock } from '../runtime/settings/control-plane.js';
|
|
7
|
-
import { requireSurfaceRoot, resolveSurfaceDirectory, resolveSurfaceSharedFile } from '../runtime/surface-root.js';
|
|
7
|
+
import { requireSurfaceRoot, resolveSharedDirectory, resolveSurfaceDirectory, resolveSurfaceSharedFile } from '../runtime/surface-root.js';
|
|
8
8
|
import { summarizeError } from '../utils/error-display.js';
|
|
9
9
|
import { toRecord } from '../utils/record-coerce.js';
|
|
10
10
|
import { migrateDangerDaemonAlias } from './migrations.js';
|
|
11
|
+
import { SHARED_CONFIG_KEYS, isSharedConfigKey, persistSharedKey, readDotPath, readSharedTierFile, removeSharedKey, } from './shared-config-tier.js';
|
|
11
12
|
const DEFAULT_CONFIG_SNAPSHOT = structuredClone(DEFAULT_CONFIG);
|
|
12
13
|
const PERMISSION_TOOL_KEYS = new Set(Object.keys(DEFAULT_CONFIG.permissions.tools));
|
|
13
14
|
function cloneDefaultConfig() {
|
|
@@ -57,6 +58,10 @@ export class ConfigManager {
|
|
|
57
58
|
projectConfigPath;
|
|
58
59
|
workingDirectory;
|
|
59
60
|
homeDirectory;
|
|
61
|
+
/** Surface-root-independent shared settings file (~/.goodvibes/shared/settings.json), or null. */
|
|
62
|
+
sharedTierPath;
|
|
63
|
+
/** Shared keys whose value the last load actually sourced from the shared tier file. */
|
|
64
|
+
sharedKeysPresent = new Set();
|
|
60
65
|
hookDispatcher = null;
|
|
61
66
|
_listeners = new Map();
|
|
62
67
|
constructor(overrides) {
|
|
@@ -82,6 +87,12 @@ export class ConfigManager {
|
|
|
82
87
|
if (ownedSharedConfigPath) {
|
|
83
88
|
ensureSharedConfig(ownedSharedConfigPath);
|
|
84
89
|
}
|
|
90
|
+
// The surface-root-INDEPENDENT shared tier for cross-surface keys (tts.*):
|
|
91
|
+
// an explicit override, else derived from homeDir as ~/.goodvibes/shared/
|
|
92
|
+
// settings.json. A configDir-only construction with no homeDir has no shared
|
|
93
|
+
// tier (legacy per-surface behavior preserved).
|
|
94
|
+
const sharedTierPath = requireAbsoluteOwnedPath(roots.sharedTierPath, 'sharedTierPath');
|
|
95
|
+
this.sharedTierPath = sharedTierPath ?? (this.homeDirectory ? resolveSharedDirectory(this.homeDirectory, 'shared', 'settings.json') : null);
|
|
85
96
|
this.load();
|
|
86
97
|
// Apply constructor overrides (CLI args, etc.) after load
|
|
87
98
|
if (overrides.model !== undefined) {
|
|
@@ -163,13 +174,23 @@ export class ConfigManager {
|
|
|
163
174
|
const { parent, field } = this.resolvePath(key);
|
|
164
175
|
const previousValue = parent[field];
|
|
165
176
|
parent[field] = value;
|
|
177
|
+
// Shared keys persist to the surface-root-independent shared tier so every
|
|
178
|
+
// surface sees the same value; everything else stays in the surface silo.
|
|
179
|
+
const useSharedTier = this.sharedTierPath !== null && isSharedConfigKey(key);
|
|
166
180
|
try {
|
|
167
|
-
|
|
181
|
+
if (useSharedTier) {
|
|
182
|
+
persistSharedKey(this.sharedTierPath, key, value);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
this.save();
|
|
186
|
+
}
|
|
168
187
|
}
|
|
169
188
|
catch (error) {
|
|
170
189
|
parent[field] = previousValue;
|
|
171
190
|
throw error;
|
|
172
191
|
}
|
|
192
|
+
if (useSharedTier)
|
|
193
|
+
this.sharedKeysPresent.add(key);
|
|
173
194
|
this.notifyListeners(key, previousValue, value);
|
|
174
195
|
this.emitConfigHook(key, previousValue, value);
|
|
175
196
|
}
|
|
@@ -299,6 +320,71 @@ export class ConfigManager {
|
|
|
299
320
|
throw new ConfigError(`Project config load failed for ${this.projectConfigPath}: ${summarizeError(err)}`);
|
|
300
321
|
}
|
|
301
322
|
}
|
|
323
|
+
// Overlay the surface-root-independent shared tier LAST (it wins over the
|
|
324
|
+
// surface silo) for the shared keys only — so every surface resolves the same
|
|
325
|
+
// voice, while a key absent from the shared file falls back to the local value.
|
|
326
|
+
this.loadSharedTier();
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Overlay any shared-tier values for the shared keys onto the resolved config.
|
|
330
|
+
* A shared key absent from the shared file is left at its surface-local value
|
|
331
|
+
* (the fallback that keeps existing setups working). Records which keys were
|
|
332
|
+
* actually sourced from the shared tier so describeConfigKeySource is honest.
|
|
333
|
+
*/
|
|
334
|
+
loadSharedTier() {
|
|
335
|
+
this.sharedKeysPresent.clear();
|
|
336
|
+
if (!this.sharedTierPath)
|
|
337
|
+
return;
|
|
338
|
+
let shared;
|
|
339
|
+
try {
|
|
340
|
+
shared = readSharedTierFile(this.sharedTierPath);
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
throw new ConfigError(`Shared config load failed for ${this.sharedTierPath}: ${summarizeError(err)}`);
|
|
344
|
+
}
|
|
345
|
+
for (const key of SHARED_CONFIG_KEYS) {
|
|
346
|
+
const found = readDotPath(shared, key);
|
|
347
|
+
if (!found.present)
|
|
348
|
+
continue;
|
|
349
|
+
const { parent, field } = this.resolvePath(key);
|
|
350
|
+
parent[field] = found.value;
|
|
351
|
+
this.sharedKeysPresent.add(key);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/** The shared-tier settings file path, or null when no shared tier is configured. */
|
|
355
|
+
getSharedTierPath() {
|
|
356
|
+
return this.sharedTierPath;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Report which tier a key's live value resolves from (shared / project / global
|
|
360
|
+
* / default) and whether it rides the shared tier. Reads the on-disk layers on
|
|
361
|
+
* demand so the resolution order is inspectable, not just documented.
|
|
362
|
+
*/
|
|
363
|
+
describeConfigKeySource(key) {
|
|
364
|
+
const value = this.get(key);
|
|
365
|
+
const shareable = isSharedConfigKey(key);
|
|
366
|
+
if (shareable && this.sharedKeysPresent.has(key)) {
|
|
367
|
+
return { key, value, tier: 'shared', shareable, sharedTierPath: this.sharedTierPath };
|
|
368
|
+
}
|
|
369
|
+
if (this.projectConfigPath && this.fileHasKey(this.projectConfigPath, key)) {
|
|
370
|
+
return { key, value, tier: 'project', shareable, sharedTierPath: this.sharedTierPath };
|
|
371
|
+
}
|
|
372
|
+
if (this.fileHasKey(this.configPath, key)) {
|
|
373
|
+
return { key, value, tier: 'global', shareable, sharedTierPath: this.sharedTierPath };
|
|
374
|
+
}
|
|
375
|
+
return { key, value, tier: 'default', shareable, sharedTierPath: this.sharedTierPath };
|
|
376
|
+
}
|
|
377
|
+
/** True when the JSON settings file at `path` carries an explicit value for `key`. */
|
|
378
|
+
fileHasKey(path, key) {
|
|
379
|
+
if (!existsSync(path))
|
|
380
|
+
return false;
|
|
381
|
+
try {
|
|
382
|
+
const parsed = JSON.parse(readFileSync(path, 'utf-8'));
|
|
383
|
+
return readDotPath(parsed, key).present;
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
302
388
|
}
|
|
303
389
|
/**
|
|
304
390
|
* Removal-of-`danger.daemon` migration (see CHANGELOG 1.0.0): rewrite an explicit legacy
|
|
@@ -365,6 +451,16 @@ export class ConfigManager {
|
|
|
365
451
|
livePath.parent[livePath.field] = structuredClone(defaultPath.parent[defaultPath.field]);
|
|
366
452
|
}
|
|
367
453
|
this.save();
|
|
454
|
+
// Reset removes the shared-tier OVERRIDE for any shared key, so the key falls
|
|
455
|
+
// back to its surface-local/default value — otherwise a stale shared value
|
|
456
|
+
// would re-overlay on the next load and defeat the reset.
|
|
457
|
+
if (this.sharedTierPath) {
|
|
458
|
+
const resetKeys = key === undefined ? SHARED_CONFIG_KEYS : (isSharedConfigKey(key) ? [key] : []);
|
|
459
|
+
for (const sharedKey of resetKeys) {
|
|
460
|
+
removeSharedKey(this.sharedTierPath, sharedKey);
|
|
461
|
+
this.sharedKeysPresent.delete(sharedKey);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
368
464
|
}
|
|
369
465
|
}
|
|
370
466
|
/** Deep-merge source into target. Returns a new object. Source non-objects are ignored — target clone is returned.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shared-config-tier.ts — the surface-root-independent config tier.
|
|
3
|
+
*
|
|
4
|
+
* A small set of keys (the voice/tts settings) must resolve to the SAME value on
|
|
5
|
+
* every surface — terminal, desktop, and the agent — rather than living in a
|
|
6
|
+
* per-surface silo (`~/.goodvibes/<surface>/settings.json`). Those keys read from
|
|
7
|
+
* and write to one neutral on-disk store, `~/.goodvibes/shared/settings.json`
|
|
8
|
+
* (the E7 shared-tier path; see docs/decisions/2026-07-06-config-sharing-shared-tier-and-secret-read.md
|
|
9
|
+
* and docs/decisions/2026-07-06-shared-voice-config-tier.md).
|
|
10
|
+
*
|
|
11
|
+
* Resolution order for a shared key: defaults < global surface < project surface
|
|
12
|
+
* < SHARED TIER < CLI overrides. A surface with no shared value falls back to its
|
|
13
|
+
* local setting, so existing setups never break; a present shared value wins so
|
|
14
|
+
* all surfaces agree.
|
|
15
|
+
*/
|
|
16
|
+
import type { ConfigKey } from './schema.js';
|
|
17
|
+
/**
|
|
18
|
+
* The keys that ride the shared, surface-root-independent tier. Currently the
|
|
19
|
+
* voice/tts settings — one voice across every surface.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SHARED_CONFIG_KEYS: readonly ConfigKey[];
|
|
22
|
+
/** True when `key` resolves from/writes to the shared tier rather than a surface silo. */
|
|
23
|
+
export declare function isSharedConfigKey(key: string): key is ConfigKey;
|
|
24
|
+
/**
|
|
25
|
+
* Read a dot-path (e.g. `tts.voice`) from a parsed-JSON object, distinguishing an
|
|
26
|
+
* absent key from a stored value (so an explicit `""` is honored, not treated as
|
|
27
|
+
* "not set").
|
|
28
|
+
*/
|
|
29
|
+
export declare function readDotPath(root: unknown, key: string): {
|
|
30
|
+
present: boolean;
|
|
31
|
+
value: unknown;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Load the shared tier file into a plain object (empty object when the file does
|
|
35
|
+
* not exist yet). Throws when the file exists but is not a JSON object — an honest
|
|
36
|
+
* loud failure rather than a silent reset, matching the surface-settings loader.
|
|
37
|
+
*/
|
|
38
|
+
export declare function readSharedTierFile(path: string): Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Persist one shared key's value into the shared tier file, merging with whatever
|
|
41
|
+
* is already there (never clobbering the other shared keys). Writes only the
|
|
42
|
+
* explicitly-set key so unrelated surface-local values are not silently promoted.
|
|
43
|
+
*/
|
|
44
|
+
export declare function persistSharedKey(path: string, key: string, value: unknown): void;
|
|
45
|
+
/**
|
|
46
|
+
* Remove one shared key from the shared tier file, so the key falls back to its
|
|
47
|
+
* surface-local or default value (used by reset). A no-op when the file or key is
|
|
48
|
+
* absent. Prunes an emptied parent object so a reset leaves no `{ tts: {} }` shell.
|
|
49
|
+
*/
|
|
50
|
+
export declare function removeSharedKey(path: string, key: string): void;
|
|
51
|
+
//# sourceMappingURL=shared-config-tier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-config-tier.d.ts","sourceRoot":"","sources":["../../../src/platform/config/shared-config-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,SAAS,EAMlD,CAAC;AAIF,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,SAAS,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAW5F;AAgBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOxE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAKhF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CA6B/D"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shared-config-tier.ts — the surface-root-independent config tier.
|
|
3
|
+
*
|
|
4
|
+
* A small set of keys (the voice/tts settings) must resolve to the SAME value on
|
|
5
|
+
* every surface — terminal, desktop, and the agent — rather than living in a
|
|
6
|
+
* per-surface silo (`~/.goodvibes/<surface>/settings.json`). Those keys read from
|
|
7
|
+
* and write to one neutral on-disk store, `~/.goodvibes/shared/settings.json`
|
|
8
|
+
* (the E7 shared-tier path; see docs/decisions/2026-07-06-config-sharing-shared-tier-and-secret-read.md
|
|
9
|
+
* and docs/decisions/2026-07-06-shared-voice-config-tier.md).
|
|
10
|
+
*
|
|
11
|
+
* Resolution order for a shared key: defaults < global surface < project surface
|
|
12
|
+
* < SHARED TIER < CLI overrides. A surface with no shared value falls back to its
|
|
13
|
+
* local setting, so existing setups never break; a present shared value wins so
|
|
14
|
+
* all surfaces agree.
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { dirname } from 'node:path';
|
|
18
|
+
/**
|
|
19
|
+
* The keys that ride the shared, surface-root-independent tier. Currently the
|
|
20
|
+
* voice/tts settings — one voice across every surface.
|
|
21
|
+
*/
|
|
22
|
+
export const SHARED_CONFIG_KEYS = [
|
|
23
|
+
'tts.provider',
|
|
24
|
+
'tts.voice',
|
|
25
|
+
'tts.speed',
|
|
26
|
+
'tts.llmProvider',
|
|
27
|
+
'tts.llmModel',
|
|
28
|
+
];
|
|
29
|
+
const SHARED_CONFIG_KEY_SET = new Set(SHARED_CONFIG_KEYS);
|
|
30
|
+
/** True when `key` resolves from/writes to the shared tier rather than a surface silo. */
|
|
31
|
+
export function isSharedConfigKey(key) {
|
|
32
|
+
return SHARED_CONFIG_KEY_SET.has(key);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Read a dot-path (e.g. `tts.voice`) from a parsed-JSON object, distinguishing an
|
|
36
|
+
* absent key from a stored value (so an explicit `""` is honored, not treated as
|
|
37
|
+
* "not set").
|
|
38
|
+
*/
|
|
39
|
+
export function readDotPath(root, key) {
|
|
40
|
+
const parts = key.split('.');
|
|
41
|
+
let cursor = root;
|
|
42
|
+
for (const part of parts) {
|
|
43
|
+
if (cursor === null || typeof cursor !== 'object' || Array.isArray(cursor)
|
|
44
|
+
|| !(part in cursor)) {
|
|
45
|
+
return { present: false, value: undefined };
|
|
46
|
+
}
|
|
47
|
+
cursor = cursor[part];
|
|
48
|
+
}
|
|
49
|
+
return { present: true, value: cursor };
|
|
50
|
+
}
|
|
51
|
+
function writeDotPath(root, key, value) {
|
|
52
|
+
const parts = key.split('.');
|
|
53
|
+
let cursor = root;
|
|
54
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
55
|
+
const part = parts[i];
|
|
56
|
+
const next = cursor[part];
|
|
57
|
+
if (next === null || typeof next !== 'object' || Array.isArray(next)) {
|
|
58
|
+
cursor[part] = {};
|
|
59
|
+
}
|
|
60
|
+
cursor = cursor[part];
|
|
61
|
+
}
|
|
62
|
+
cursor[parts[parts.length - 1]] = value;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Load the shared tier file into a plain object (empty object when the file does
|
|
66
|
+
* not exist yet). Throws when the file exists but is not a JSON object — an honest
|
|
67
|
+
* loud failure rather than a silent reset, matching the surface-settings loader.
|
|
68
|
+
*/
|
|
69
|
+
export function readSharedTierFile(path) {
|
|
70
|
+
if (!existsSync(path))
|
|
71
|
+
return {};
|
|
72
|
+
const parsed = JSON.parse(readFileSync(path, 'utf-8'));
|
|
73
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
74
|
+
throw new Error('shared tier settings file is not a JSON object');
|
|
75
|
+
}
|
|
76
|
+
return parsed;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Persist one shared key's value into the shared tier file, merging with whatever
|
|
80
|
+
* is already there (never clobbering the other shared keys). Writes only the
|
|
81
|
+
* explicitly-set key so unrelated surface-local values are not silently promoted.
|
|
82
|
+
*/
|
|
83
|
+
export function persistSharedKey(path, key, value) {
|
|
84
|
+
const existing = readSharedTierFile(path);
|
|
85
|
+
writeDotPath(existing, key, value);
|
|
86
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
87
|
+
writeFileSync(path, JSON.stringify(existing, null, 2) + '\n', 'utf-8');
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Remove one shared key from the shared tier file, so the key falls back to its
|
|
91
|
+
* surface-local or default value (used by reset). A no-op when the file or key is
|
|
92
|
+
* absent. Prunes an emptied parent object so a reset leaves no `{ tts: {} }` shell.
|
|
93
|
+
*/
|
|
94
|
+
export function removeSharedKey(path, key) {
|
|
95
|
+
if (!existsSync(path))
|
|
96
|
+
return;
|
|
97
|
+
const existing = readSharedTierFile(path);
|
|
98
|
+
const parts = key.split('.');
|
|
99
|
+
const parents = [existing];
|
|
100
|
+
let cursor = existing;
|
|
101
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
102
|
+
const next = cursor[parts[i]];
|
|
103
|
+
if (next === null || typeof next !== 'object' || Array.isArray(next))
|
|
104
|
+
return;
|
|
105
|
+
cursor = next;
|
|
106
|
+
parents.push(cursor);
|
|
107
|
+
}
|
|
108
|
+
const leaf = parts[parts.length - 1];
|
|
109
|
+
if (!(leaf in cursor))
|
|
110
|
+
return;
|
|
111
|
+
delete cursor[leaf];
|
|
112
|
+
// Prune now-empty parent objects from the deepest up.
|
|
113
|
+
for (let i = parts.length - 2; i >= 0; i--) {
|
|
114
|
+
const parent = parents[i];
|
|
115
|
+
const childKey = parts[i];
|
|
116
|
+
const child = parent[childKey];
|
|
117
|
+
if (child && typeof child === 'object' && !Array.isArray(child)
|
|
118
|
+
&& Object.keys(child).length === 0) {
|
|
119
|
+
delete parent[childKey];
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
126
|
+
writeFileSync(path, JSON.stringify(existing, null, 2) + '\n', 'utf-8');
|
|
127
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operator-contract-schemas-knowledge.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/operator-contract-schemas-knowledge.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,qCAAqC,yBAA6C,CAAC;AAChG,eAAO,MAAM,iCAAiC,yBAAqC,CAAC;AACpF,eAAO,MAAM,oCAAoC,yBAA4B,CAAC;AAC9E,eAAO,MAAM,sCAAsC,yBAAqE,CAAC;AACzH,eAAO,MAAM,4BAA4B,yBAWvC,CAAC;AACH,eAAO,MAAM,8BAA8B,yBAAkD,CAAC;AAC9F,eAAO,MAAM,yBAAyB,yBAAuC,CAAC;AAC9E,eAAO,MAAM,2BAA2B,yBAA2D,CAAC;AACpG,eAAO,MAAM,sCAAsC,yBAcjD,CAAC;AACH,eAAO,MAAM,wCAAwC,yBAOnD,CAAC;AACH,eAAO,MAAM,yCAAyC,yBAAkD,CAAC;AACzG,eAAO,MAAM,yBAAyB,yBAWpC,CAAC;AACH,eAAO,MAAM,uCAAuC,yBAAgD,CAAC;AACrG,eAAO,MAAM,2CAA2C,yBAAmE,CAAC;AAC5H,eAAO,MAAM,6CAA6C,yBAQxD,CAAC;AACH,eAAO,MAAM,wCAAwC,yBAAuC,CAAC;AAwB7F,eAAO,MAAM,oCAAoC;;CAMvC,CAAC;AACX,eAAO,MAAM,+BAA+B;;CAOlC,CAAC;AA4DX,eAAO,MAAM,+BAA+B;;CAYlC,CAAC;AACX,eAAO,MAAM,gCAAgC,yBAIN,CAAC;AACxC,eAAO,MAAM,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiB1C,CAAC;AACX,eAAO,MAAM,qCAAqC,yBAOM,CAAC;AACzD,eAAO,MAAM,0BAA0B,yBAY4H,CAAC;AACpK,eAAO,MAAM,iCAAiC,yBAGI,CAAC;AAEnD,eAAO,MAAM,uBAAuB,yBAoB2F,CAAC;AAEhI,eAAO,MAAM,qBAAqB,yBAiB0G,CAAC;AAE7I,eAAO,MAAM,sBAAsB,yBAWsF,CAAC;AAE1H,eAAO,MAAM,qBAAqB,yBAW4G,CAAC;AAE/I,eAAO,MAAM,2BAA2B,yBAgBkI,CAAC;AAE3K,eAAO,MAAM,uBAAuB,yBAciL,CAAC;AAEtN,eAAO,MAAM,gCAAgC,yBAyBiH,CAAC;AAE/J,eAAO,MAAM,wCAAwC,yBAER,CAAC;AAE9C,eAAO,MAAM,uCAAuC,yBAER,CAAC;AAE7C,eAAO,MAAM,sCAAsC,yBAsB4H,CAAC;AAEhL,eAAO,MAAM,0BAA0B,yBAOD,CAAC;AAoBvC,eAAO,MAAM,0BAA0B,yBAWgC,CAAC;AAmBxE,eAAO,MAAM,8BAA8B,yBAIa,CAAC;AAEzD,eAAO,MAAM,oCAAoC,yBAKF,CAAC;AAWhD,eAAO,MAAM,oCAAoC,yBAMU,CAAC;AAW5D,eAAO,MAAM,8BAA8B,yBAE5B,CAAC;AAEhB,eAAO,MAAM,2BAA2B,yBAe2C,CAAC;AAEpF,eAAO,MAAM,+BAA+B,yBAAuD,CAAC;AACpG,eAAO,MAAM,6BAA6B,yBAAmD,CAAC;AAC9F,eAAO,MAAM,8BAA8B,yBAAqD,CAAC;AACjG,eAAO,MAAM,oCAAoC,yBAOE,CAAC;AACpD,eAAO,MAAM,kCAAkC,yBAA6D,CAAC;AAgB7G,eAAO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"operator-contract-schemas-knowledge.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/operator-contract-schemas-knowledge.ts"],"names":[],"mappings":"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"}
|