@lunora/config 1.0.0-alpha.10 → 1.0.0-alpha.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.d.mts CHANGED
@@ -777,6 +777,58 @@ declare const buildPackageSecretsBlock: (packageNames: ReadonlyArray<string>, ex
777
777
  * **Safety invariant:** only placeholder values are written — no real secrets.
778
778
  */
779
779
  declare const ensureDevVariablesExample: (cwd: string, packageNames: ReadonlyArray<string>) => string[];
780
+ interface DevSecretsFillPlan {
781
+ /** {@link CORE_SECRETS} keys appended because they were absent (each generated). */
782
+ addedKeys: string[];
783
+ /** The full new file content to write. */
784
+ content: string;
785
+ /** Existing empty/placeholder secret-keyed entries filled with fresh values. */
786
+ filledKeys: string[];
787
+ }
788
+ /**
789
+ * Plan the in-place generation of dev secrets for a `.dev.vars`. First, every
790
+ * line whose KEY looks like a secret (`*_SECRET`, `*_TOKEN`, `*_KEY`,
791
+ * `*_PASSWORD`) and whose value is empty or a placeholder gets a freshly
792
+ * generated value — so a `lunora add`-scaffolded `.dev.vars` (which writes each
793
+ * secret blank) becomes usable on `lunora dev` / `vite dev` without the user
794
+ * running `openssl` by hand. Second, any {@link CORE_SECRETS} key absent from
795
+ * the file is appended (generated) — notably `LUNORA_ADMIN_TOKEN`, which the
796
+ * local Studio needs to call the worker's admin gate in dev (without it the
797
+ * Studio shows its login gate).
798
+ *
799
+ * Pure (given `randomHex`): real (non-placeholder) values are never touched, and
800
+ * comments + non-secret entries are preserved verbatim.
801
+ */
802
+ declare const planDevSecretsFill: (input: {
803
+ existingContent: string;
804
+ randomHex?: (bytes: number) => string;
805
+ }) => DevSecretsFillPlan;
806
+ interface FillDevSecretsResult {
807
+ /** Core secret keys appended (generated) because they were missing. */
808
+ addedKeys: string[];
809
+ /** Existing empty/placeholder secrets filled with generated values. */
810
+ filledKeys: string[];
811
+ /** `created` = no `.dev.vars` existed; `filled` = topped up an existing one; `unchanged` = nothing to do. */
812
+ status: "created" | "filled" | "unchanged";
813
+ }
814
+ /**
815
+ * Generate any missing/empty dev secrets in the project's `.dev.vars`, in place.
816
+ *
817
+ * Complements {@link ensureDevVariables} (which scaffolds `.dev.vars` from
818
+ * `.dev.vars.example`). A `lunora add`-scaffolded project writes secrets blank
819
+ * straight into `.dev.vars` (no example) and never includes `LUNORA_ADMIN_TOKEN`
820
+ * — so the worker boots with empty secrets and the Studio shows its login gate.
821
+ * This fills those gaps at dev startup, so both `lunora dev` and the
822
+ * `@lunora/vite` dev server give a working project with zero manual `openssl`.
823
+ *
824
+ * Never overwrites a real (non-placeholder) value. The write is atomic + owner-
825
+ * only (temp + rename, `mode: 0o600`), matching the other `.dev.vars` writers.
826
+ */
827
+ declare const fillDevSecrets: (deps: {
828
+ cwd: string;
829
+ info?: (message: string) => void;
830
+ randomHex?: (bytes: number) => string;
831
+ }) => FillDevSecretsResult;
780
832
  /** Add a new table to `defineSchema({ ... })`. */
781
833
  interface AddTableEdit {
782
834
  readonly kind: "addTable";
@@ -1137,4 +1189,4 @@ interface WranglerProjectValidationResult {
1137
1189
  * `{ problems, wranglerPath }` shape plus the structured `report`.
1138
1190
  */
1139
1191
  declare const validateWranglerProject: (options: WranglerProjectValidationOptions) => WranglerProjectValidationResult;
1140
- export { ACCENT, AGENT_RULES_DIR, AGENT_RULES_HINT, AGENT_RULES_HINT_ENV, type AddIndexEdit, type AddOptionalColumnEdit, type AddTableEdit, type AdditiveEdit, type AgentRulesStatus, type ApplyEditResult, type ApplyFailureReason, type AugmentPlan, BADGES, BADGE_COLUMN_WIDTH, type BadgeName, type BadgeSpec, DEV_VARS_EXAMPLE_FILE, DEV_VARS_FILE, DEV_VARS_KEY_PATTERN, type DestructiveEdit, type DetectedFramework, type DiscoverContainerInfoResult, type DiscoverSchemaInfoResult, type DiscoverWorkflowInfoResult, type EnsureDevVariablesDeps, type EnsureDevVariablesResult, type EnsureDevVariablesStatus, type ExportGap, type FrameworkClass, type FrameworkDetection, type InferOptions, type InferredBindings, type InferredContainer, type InferredWorkflow, LINKED_PROJECT_DIR, LINKED_PROJECT_FILE, LUNA_ART, LUNA_BUNNY, LUNA_NAME, LUNA_SIGNOFF, LUNORA_CONFIG_FILE, LUNORA_EVENT_SOURCE, LUNORA_SKILL_NAMES, type LevelBadgeName, type LinkedProject, type LunoraFormattedLine, type LunoraLineLevel, type LunoraProjectConfig, LunoraReporter, type MaterializeOptions, type MaterializeResult, type MultiSelectOption, PACKAGE_SECRETS_REGISTRY, type ParseSchemaResult, REMOTE_ELIGIBLE_KEYS, REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, ROOT_SKILL_NAME, type ReadWranglerResult, type ReconcileBindingsResult, type RemoteBindingPlan, type RemoteEnableInputs, type RemotePreference, type RemoteWranglerShape, STEP_BADGE_NAMES, type ScaffoldPlan, type SchemaColumn, type SchemaEdit, type SchemaIndex, type SchemaInfo, type SchemaTable, type SecretEntry, type SelectOption, type StepBadgeName, type TailConsumer, WRANGLER_FILES, type WranglerConfig, type WranglerContainerEntry, type WranglerProjectValidationOptions, type WranglerProjectValidationResult, type WranglerValidationReport, type WranglerWorkflowEntry, applyAdditiveEdit, badgeLead, badgeWidth, buildPackageSecretsBlock, claimAgentRulesHint, classifyEdit, createConfirm, detectAgentRules, detectFramework, discoverContainerInfo, discoverSchemaInfo, discoverWorkflowInfo, ensureDevVariables, ensureDevVariablesExample as ensureDevVarsExample, findWranglerFile, formatLunoraEvent, inferLunoraBindings, injectRemoteFlags, interpretRemote, isInteractive, isPlaceholderValue, isRemoteEnvEnabled, materializeRemoteWranglerConfig, packageNamesFromBindings, padBadge, paintAnswer, paintBadge, parseDevVariableEntries, parseSchema, planDevVariablesAugment, planDevVariablesScaffold, planRemoteBindings, promptMultiSelect, promptSelect, promptYesNo, readLinkedProject, readProjectRemotePreference, readWranglerJsonc, reconcileWranglerBindings, resolveRemoteEnabled, secretsForPackages, validateWrangler, validateWranglerConfig, validateWranglerProject, withTailConsumer, writeLinkedProject };
1192
+ export { ACCENT, AGENT_RULES_DIR, AGENT_RULES_HINT, AGENT_RULES_HINT_ENV, type AddIndexEdit, type AddOptionalColumnEdit, type AddTableEdit, type AdditiveEdit, type AgentRulesStatus, type ApplyEditResult, type ApplyFailureReason, type AugmentPlan, BADGES, BADGE_COLUMN_WIDTH, type BadgeName, type BadgeSpec, DEV_VARS_EXAMPLE_FILE, DEV_VARS_FILE, DEV_VARS_KEY_PATTERN, type DestructiveEdit, type DetectedFramework, type DevSecretsFillPlan, type DiscoverContainerInfoResult, type DiscoverSchemaInfoResult, type DiscoverWorkflowInfoResult, type EnsureDevVariablesDeps, type EnsureDevVariablesResult, type EnsureDevVariablesStatus, type ExportGap, type FillDevSecretsResult, type FrameworkClass, type FrameworkDetection, type InferOptions, type InferredBindings, type InferredContainer, type InferredWorkflow, LINKED_PROJECT_DIR, LINKED_PROJECT_FILE, LUNA_ART, LUNA_BUNNY, LUNA_NAME, LUNA_SIGNOFF, LUNORA_CONFIG_FILE, LUNORA_EVENT_SOURCE, LUNORA_SKILL_NAMES, type LevelBadgeName, type LinkedProject, type LunoraFormattedLine, type LunoraLineLevel, type LunoraProjectConfig, LunoraReporter, type MaterializeOptions, type MaterializeResult, type MultiSelectOption, PACKAGE_SECRETS_REGISTRY, type ParseSchemaResult, REMOTE_ELIGIBLE_KEYS, REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, ROOT_SKILL_NAME, type ReadWranglerResult, type ReconcileBindingsResult, type RemoteBindingPlan, type RemoteEnableInputs, type RemotePreference, type RemoteWranglerShape, STEP_BADGE_NAMES, type ScaffoldPlan, type SchemaColumn, type SchemaEdit, type SchemaIndex, type SchemaInfo, type SchemaTable, type SecretEntry, type SelectOption, type StepBadgeName, type TailConsumer, WRANGLER_FILES, type WranglerConfig, type WranglerContainerEntry, type WranglerProjectValidationOptions, type WranglerProjectValidationResult, type WranglerValidationReport, type WranglerWorkflowEntry, applyAdditiveEdit, badgeLead, badgeWidth, buildPackageSecretsBlock, claimAgentRulesHint, classifyEdit, createConfirm, detectAgentRules, detectFramework, discoverContainerInfo, discoverSchemaInfo, discoverWorkflowInfo, ensureDevVariables, ensureDevVariablesExample as ensureDevVarsExample, fillDevSecrets, findWranglerFile, formatLunoraEvent, inferLunoraBindings, injectRemoteFlags, interpretRemote, isInteractive, isPlaceholderValue, isRemoteEnvEnabled, materializeRemoteWranglerConfig, packageNamesFromBindings, padBadge, paintAnswer, paintBadge, parseDevVariableEntries, parseSchema, planDevSecretsFill, planDevVariablesAugment, planDevVariablesScaffold, planRemoteBindings, promptMultiSelect, promptSelect, promptYesNo, readLinkedProject, readProjectRemotePreference, readWranglerJsonc, reconcileWranglerBindings, resolveRemoteEnabled, secretsForPackages, validateWrangler, validateWranglerConfig, validateWranglerProject, withTailConsumer, writeLinkedProject };
package/dist/index.d.ts CHANGED
@@ -777,6 +777,58 @@ declare const buildPackageSecretsBlock: (packageNames: ReadonlyArray<string>, ex
777
777
  * **Safety invariant:** only placeholder values are written — no real secrets.
778
778
  */
779
779
  declare const ensureDevVariablesExample: (cwd: string, packageNames: ReadonlyArray<string>) => string[];
780
+ interface DevSecretsFillPlan {
781
+ /** {@link CORE_SECRETS} keys appended because they were absent (each generated). */
782
+ addedKeys: string[];
783
+ /** The full new file content to write. */
784
+ content: string;
785
+ /** Existing empty/placeholder secret-keyed entries filled with fresh values. */
786
+ filledKeys: string[];
787
+ }
788
+ /**
789
+ * Plan the in-place generation of dev secrets for a `.dev.vars`. First, every
790
+ * line whose KEY looks like a secret (`*_SECRET`, `*_TOKEN`, `*_KEY`,
791
+ * `*_PASSWORD`) and whose value is empty or a placeholder gets a freshly
792
+ * generated value — so a `lunora add`-scaffolded `.dev.vars` (which writes each
793
+ * secret blank) becomes usable on `lunora dev` / `vite dev` without the user
794
+ * running `openssl` by hand. Second, any {@link CORE_SECRETS} key absent from
795
+ * the file is appended (generated) — notably `LUNORA_ADMIN_TOKEN`, which the
796
+ * local Studio needs to call the worker's admin gate in dev (without it the
797
+ * Studio shows its login gate).
798
+ *
799
+ * Pure (given `randomHex`): real (non-placeholder) values are never touched, and
800
+ * comments + non-secret entries are preserved verbatim.
801
+ */
802
+ declare const planDevSecretsFill: (input: {
803
+ existingContent: string;
804
+ randomHex?: (bytes: number) => string;
805
+ }) => DevSecretsFillPlan;
806
+ interface FillDevSecretsResult {
807
+ /** Core secret keys appended (generated) because they were missing. */
808
+ addedKeys: string[];
809
+ /** Existing empty/placeholder secrets filled with generated values. */
810
+ filledKeys: string[];
811
+ /** `created` = no `.dev.vars` existed; `filled` = topped up an existing one; `unchanged` = nothing to do. */
812
+ status: "created" | "filled" | "unchanged";
813
+ }
814
+ /**
815
+ * Generate any missing/empty dev secrets in the project's `.dev.vars`, in place.
816
+ *
817
+ * Complements {@link ensureDevVariables} (which scaffolds `.dev.vars` from
818
+ * `.dev.vars.example`). A `lunora add`-scaffolded project writes secrets blank
819
+ * straight into `.dev.vars` (no example) and never includes `LUNORA_ADMIN_TOKEN`
820
+ * — so the worker boots with empty secrets and the Studio shows its login gate.
821
+ * This fills those gaps at dev startup, so both `lunora dev` and the
822
+ * `@lunora/vite` dev server give a working project with zero manual `openssl`.
823
+ *
824
+ * Never overwrites a real (non-placeholder) value. The write is atomic + owner-
825
+ * only (temp + rename, `mode: 0o600`), matching the other `.dev.vars` writers.
826
+ */
827
+ declare const fillDevSecrets: (deps: {
828
+ cwd: string;
829
+ info?: (message: string) => void;
830
+ randomHex?: (bytes: number) => string;
831
+ }) => FillDevSecretsResult;
780
832
  /** Add a new table to `defineSchema({ ... })`. */
781
833
  interface AddTableEdit {
782
834
  readonly kind: "addTable";
@@ -1137,4 +1189,4 @@ interface WranglerProjectValidationResult {
1137
1189
  * `{ problems, wranglerPath }` shape plus the structured `report`.
1138
1190
  */
1139
1191
  declare const validateWranglerProject: (options: WranglerProjectValidationOptions) => WranglerProjectValidationResult;
1140
- export { ACCENT, AGENT_RULES_DIR, AGENT_RULES_HINT, AGENT_RULES_HINT_ENV, type AddIndexEdit, type AddOptionalColumnEdit, type AddTableEdit, type AdditiveEdit, type AgentRulesStatus, type ApplyEditResult, type ApplyFailureReason, type AugmentPlan, BADGES, BADGE_COLUMN_WIDTH, type BadgeName, type BadgeSpec, DEV_VARS_EXAMPLE_FILE, DEV_VARS_FILE, DEV_VARS_KEY_PATTERN, type DestructiveEdit, type DetectedFramework, type DiscoverContainerInfoResult, type DiscoverSchemaInfoResult, type DiscoverWorkflowInfoResult, type EnsureDevVariablesDeps, type EnsureDevVariablesResult, type EnsureDevVariablesStatus, type ExportGap, type FrameworkClass, type FrameworkDetection, type InferOptions, type InferredBindings, type InferredContainer, type InferredWorkflow, LINKED_PROJECT_DIR, LINKED_PROJECT_FILE, LUNA_ART, LUNA_BUNNY, LUNA_NAME, LUNA_SIGNOFF, LUNORA_CONFIG_FILE, LUNORA_EVENT_SOURCE, LUNORA_SKILL_NAMES, type LevelBadgeName, type LinkedProject, type LunoraFormattedLine, type LunoraLineLevel, type LunoraProjectConfig, LunoraReporter, type MaterializeOptions, type MaterializeResult, type MultiSelectOption, PACKAGE_SECRETS_REGISTRY, type ParseSchemaResult, REMOTE_ELIGIBLE_KEYS, REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, ROOT_SKILL_NAME, type ReadWranglerResult, type ReconcileBindingsResult, type RemoteBindingPlan, type RemoteEnableInputs, type RemotePreference, type RemoteWranglerShape, STEP_BADGE_NAMES, type ScaffoldPlan, type SchemaColumn, type SchemaEdit, type SchemaIndex, type SchemaInfo, type SchemaTable, type SecretEntry, type SelectOption, type StepBadgeName, type TailConsumer, WRANGLER_FILES, type WranglerConfig, type WranglerContainerEntry, type WranglerProjectValidationOptions, type WranglerProjectValidationResult, type WranglerValidationReport, type WranglerWorkflowEntry, applyAdditiveEdit, badgeLead, badgeWidth, buildPackageSecretsBlock, claimAgentRulesHint, classifyEdit, createConfirm, detectAgentRules, detectFramework, discoverContainerInfo, discoverSchemaInfo, discoverWorkflowInfo, ensureDevVariables, ensureDevVariablesExample as ensureDevVarsExample, findWranglerFile, formatLunoraEvent, inferLunoraBindings, injectRemoteFlags, interpretRemote, isInteractive, isPlaceholderValue, isRemoteEnvEnabled, materializeRemoteWranglerConfig, packageNamesFromBindings, padBadge, paintAnswer, paintBadge, parseDevVariableEntries, parseSchema, planDevVariablesAugment, planDevVariablesScaffold, planRemoteBindings, promptMultiSelect, promptSelect, promptYesNo, readLinkedProject, readProjectRemotePreference, readWranglerJsonc, reconcileWranglerBindings, resolveRemoteEnabled, secretsForPackages, validateWrangler, validateWranglerConfig, validateWranglerProject, withTailConsumer, writeLinkedProject };
1192
+ export { ACCENT, AGENT_RULES_DIR, AGENT_RULES_HINT, AGENT_RULES_HINT_ENV, type AddIndexEdit, type AddOptionalColumnEdit, type AddTableEdit, type AdditiveEdit, type AgentRulesStatus, type ApplyEditResult, type ApplyFailureReason, type AugmentPlan, BADGES, BADGE_COLUMN_WIDTH, type BadgeName, type BadgeSpec, DEV_VARS_EXAMPLE_FILE, DEV_VARS_FILE, DEV_VARS_KEY_PATTERN, type DestructiveEdit, type DetectedFramework, type DevSecretsFillPlan, type DiscoverContainerInfoResult, type DiscoverSchemaInfoResult, type DiscoverWorkflowInfoResult, type EnsureDevVariablesDeps, type EnsureDevVariablesResult, type EnsureDevVariablesStatus, type ExportGap, type FillDevSecretsResult, type FrameworkClass, type FrameworkDetection, type InferOptions, type InferredBindings, type InferredContainer, type InferredWorkflow, LINKED_PROJECT_DIR, LINKED_PROJECT_FILE, LUNA_ART, LUNA_BUNNY, LUNA_NAME, LUNA_SIGNOFF, LUNORA_CONFIG_FILE, LUNORA_EVENT_SOURCE, LUNORA_SKILL_NAMES, type LevelBadgeName, type LinkedProject, type LunoraFormattedLine, type LunoraLineLevel, type LunoraProjectConfig, LunoraReporter, type MaterializeOptions, type MaterializeResult, type MultiSelectOption, PACKAGE_SECRETS_REGISTRY, type ParseSchemaResult, REMOTE_ELIGIBLE_KEYS, REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, ROOT_SKILL_NAME, type ReadWranglerResult, type ReconcileBindingsResult, type RemoteBindingPlan, type RemoteEnableInputs, type RemotePreference, type RemoteWranglerShape, STEP_BADGE_NAMES, type ScaffoldPlan, type SchemaColumn, type SchemaEdit, type SchemaIndex, type SchemaInfo, type SchemaTable, type SecretEntry, type SelectOption, type StepBadgeName, type TailConsumer, WRANGLER_FILES, type WranglerConfig, type WranglerContainerEntry, type WranglerProjectValidationOptions, type WranglerProjectValidationResult, type WranglerValidationReport, type WranglerWorkflowEntry, applyAdditiveEdit, badgeLead, badgeWidth, buildPackageSecretsBlock, claimAgentRulesHint, classifyEdit, createConfirm, detectAgentRules, detectFramework, discoverContainerInfo, discoverSchemaInfo, discoverWorkflowInfo, ensureDevVariables, ensureDevVariablesExample as ensureDevVarsExample, fillDevSecrets, findWranglerFile, formatLunoraEvent, inferLunoraBindings, injectRemoteFlags, interpretRemote, isInteractive, isPlaceholderValue, isRemoteEnvEnabled, materializeRemoteWranglerConfig, packageNamesFromBindings, padBadge, paintAnswer, paintBadge, parseDevVariableEntries, parseSchema, planDevSecretsFill, planDevVariablesAugment, planDevVariablesScaffold, planRemoteBindings, promptMultiSelect, promptSelect, promptYesNo, readLinkedProject, readProjectRemotePreference, readWranglerJsonc, reconcileWranglerBindings, resolveRemoteEnabled, secretsForPackages, validateWrangler, validateWranglerConfig, validateWranglerProject, withTailConsumer, writeLinkedProject };
package/dist/index.mjs CHANGED
@@ -11,7 +11,7 @@ export { LUNORA_CONFIG_FILE, interpretRemote, readProjectRemotePreference } from
11
11
  export { createConfirm, isInteractive, promptMultiSelect, promptSelect, promptYesNo } from './packem_shared/createConfirm-fvpdgJ9s.mjs';
12
12
  export { reconcileWranglerBindings } from './packem_shared/reconcileWranglerBindings-DTHmqTbL.mjs';
13
13
  export { REMOTE_ELIGIBLE_KEYS, injectRemoteFlags, isRemoteEnvEnabled, materializeRemoteWranglerConfig, planRemoteBindings, resolveRemoteEnabled } from './packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs';
14
- export { buildPackageSecretsBlock, ensureDevVariables, ensureDevVarsExample, isPlaceholderValue, planDevVariablesAugment, planDevVariablesScaffold } from './packem_shared/buildPackageSecretsBlock-DNzNRu7T.mjs';
14
+ export { buildPackageSecretsBlock, ensureDevVariables, ensureDevVarsExample, fillDevSecrets, isPlaceholderValue, planDevSecretsFill, planDevVariablesAugment, planDevVariablesScaffold } from './packem_shared/buildPackageSecretsBlock-nbqOA644.mjs';
15
15
  export { applyAdditiveEdit, classifyEdit } from './packem_shared/applyAdditiveEdit-C-snTFEV.mjs';
16
16
  export { parseSchema } from './packem_shared/parseSchema-DSeyktvG.mjs';
17
17
  export { classifyPolicyEdit, scaffoldPolicyFile, wireRlsIntoProcedure } from './packem_shared/classifyPolicyEdit-BHeAqF8P.mjs';
@@ -184,5 +184,55 @@ ${block}
184
184
  }
185
185
  return requiredSecrets(packageNames).filter((entry) => !existingKeys.has(entry.key)).map((entry) => entry.key);
186
186
  };
187
+ const planDevSecretsFill = (input) => {
188
+ const randomHex = input.randomHex ?? defaultRandomHex;
189
+ const filledKeys = [];
190
+ const lines = input.existingContent.split(DEV_VARS_NEWLINE).map((line) => {
191
+ const parsed = splitDevVariableLine(line);
192
+ const secret = parsed ? generatedSecretFor(parsed.key, parsed.value, randomHex) : void 0;
193
+ if (!parsed || secret === void 0) {
194
+ return line;
195
+ }
196
+ filledKeys.push(parsed.key);
197
+ return `${parsed.key}="${secret}"`;
198
+ });
199
+ const present = new Set(parseDevVariableEntries(input.existingContent).map((entry) => entry.key));
200
+ const addedKeys = [];
201
+ const additions = [];
202
+ for (const entry of CORE_SECRETS) {
203
+ if (present.has(entry.key)) {
204
+ continue;
205
+ }
206
+ addedKeys.push(entry.key);
207
+ additions.push(`# ${entry.description}`, `${entry.key}="${randomHex(SECRET_BYTES)}"`);
208
+ }
209
+ const body = lines.join("\n");
210
+ if (additions.length === 0) {
211
+ return { addedKeys, content: body, filledKeys };
212
+ }
213
+ const separator = body === "" || body.endsWith("\n") ? "" : "\n";
214
+ return { addedKeys, content: `${body}${separator}${additions.join("\n")}
215
+ `, filledKeys };
216
+ };
217
+ const fillDevSecrets = (deps) => {
218
+ const devVariablesPath = join(deps.cwd, DEV_VARS_FILE);
219
+ const exists = existsSync(devVariablesPath);
220
+ const existingContent = exists ? readFileSync(devVariablesPath, "utf8") : "";
221
+ const plan = planDevSecretsFill({ existingContent, randomHex: deps.randomHex });
222
+ if (plan.filledKeys.length === 0 && plan.addedKeys.length === 0) {
223
+ return { addedKeys: [], filledKeys: [], status: "unchanged" };
224
+ }
225
+ const temporaryPath = `${devVariablesPath}.tmp-${String(process.pid)}`;
226
+ try {
227
+ writeFileSync(temporaryPath, plan.content, { encoding: "utf8", mode: 384 });
228
+ renameSync(temporaryPath, devVariablesPath);
229
+ } catch (error) {
230
+ rmSync(temporaryPath, { force: true });
231
+ throw error;
232
+ }
233
+ const generated = [...plan.filledKeys, ...plan.addedKeys];
234
+ deps.info?.(`Generated ${String(generated.length)} dev secret(s) in ${DEV_VARS_FILE}: ${generated.join(", ")}`);
235
+ return { addedKeys: plan.addedKeys, filledKeys: plan.filledKeys, status: exists ? "filled" : "created" };
236
+ };
187
237
 
188
- export { buildPackageSecretsBlock, ensureDevVariables, ensureDevVariablesExample as ensureDevVarsExample, isPlaceholderValue, planDevVariablesAugment, planDevVariablesScaffold };
238
+ export { buildPackageSecretsBlock, ensureDevVariables, ensureDevVariablesExample as ensureDevVarsExample, fillDevSecrets, isPlaceholderValue, planDevSecretsFill, planDevVariablesAugment, planDevVariablesScaffold };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/config",
3
- "version": "1.0.0-alpha.10",
3
+ "version": "1.0.0-alpha.12",
4
4
  "description": "Internal shared CLI + Vite config layer for Lunora: wrangler.jsonc validation, binding inference, and .dev.vars scaffolding",
5
5
  "keywords": [
6
6
  "bindings",
@@ -59,7 +59,7 @@
59
59
  "ts-morph": "^28.0.0"
60
60
  },
61
61
  "peerDependencies": {
62
- "@lunora/studio": "1.0.0-alpha.4"
62
+ "@lunora/studio": "1.0.0-alpha.5"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
65
  "@lunora/studio": {