atmn 2.0.11 → 2.0.13

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.
@@ -1 +1 @@
1
- {"version":"7.0.0-dev.20260511.1","root":["../src/bin.ts","../src/cli.ts","../src/index.ts","../src/version.ts","../src/actions/env.ts","../src/actions/login.ts","../src/actions/pull.ts","../src/actions/push.ts","../src/actions/api/callApi.ts","../src/actions/api/registerApiCommands.ts","../src/actions/env/fetchOrgInfo.ts","../src/actions/env/types/orgInfo.ts","../src/actions/init/runInit.ts","../src/actions/login/keyless.ts","../src/actions/pull/appendPlanVersionFixture.ts","../src/actions/pull/applyPreview.ts","../src/actions/pull/applySettingsPreview.ts","../src/actions/pull/changedFixtureKeys.ts","../src/actions/pull/listSourceFiles.ts","../src/actions/pull/locateFixture.ts","../src/actions/pull/resolveCollectionTarget.ts","../src/actions/pull/rewriteConfig.ts","../src/actions/pull/scaffoldConfig.ts","../src/actions/push/backfillInternalIds.ts","../src/actions/push/deprecatedFields.ts","../src/actions/reset/runReset.ts","../src/actions/sandbox/createSandbox.ts","../src/actions/sandbox/deleteSandbox.ts","../src/actions/sandbox/listSandboxes.ts","../src/actions/sandbox/useSandbox.ts","../src/actions/sandbox/withSandboxScopeHint.ts","../src/actions/sandbox/types/sandboxClient.ts","../src/actions/skills/skills.ts","../src/auth/announceAuthorizationUrl.ts","../src/auth/buildAuthorizationUrl.ts","../src/auth/callbackPages.ts","../src/auth/createOrgApiKeys.ts","../src/auth/keyless.ts","../src/auth/oauthConfig.ts","../src/auth/runOAuthFlow.ts","../src/auth/browser/openSystemBrowser.ts","../src/auth/browser/tryOpenBrowser.ts","../src/auth/browser/watchLauncher.ts","../src/auth/types/browserOpener.ts","../src/auth/types/impersonationTokens.ts","../src/auth/types/oauthTokens.ts","../src/auth/types/orgApiKeys.ts","../src/config/configPackageName.ts","../src/config/legacyConfig.ts","../src/config/loadConfig.ts","../src/env/assertSandboxTarget.ts","../src/env/loadEnv.ts","../src/env/resolveTarget.ts","../src/env/sandboxKeyName.ts","../src/generated/apiRoutes.ts","../src/generated/client.ts","../src/generated/emit.ts","../src/generated/emitRuntime.ts","../src/generated/features.ts","../src/generated/labels.ts","../src/generated/licenses.ts","../src/generated/lintRules.ts","../src/generated/lintRuntime.ts","../src/generated/plans.ts","../src/generated/referralPrograms.ts","../src/generated/rewards.ts","../src/generated/settings.ts","../src/generated/skills.ts","../src/generated/variants.ts","../src/generated/wire.ts","../src/http/autumnFetch.ts","../src/project/chooseConfigDir.ts","../src/project/resolveProject.ts","../src/project/rootMarker.ts","../src/prompt/prompt.ts","../src/prompt/select.ts","../src/render/renderEnv.ts","../src/render/renderPreview.ts","../src/render/renderSandboxes.ts","../src/render/stripTerminalControls.ts","../src/repo/findRepoRoot.ts","../src/surgery/appendPropertyEdit.ts","../src/surgery/appendToArray.ts","../src/surgery/appendToBinding.ts","../src/surgery/appendToCollection.ts","../src/surgery/appendToFixtureArray.ts","../src/surgery/arrayBinding.ts","../src/surgery/deleteFixtureLiteral.ts","../src/surgery/deleteReference.ts","../src/surgery/ensureBuilderImport.ts","../src/surgery/findFixture.ts","../src/surgery/fixtureEdit.ts","../src/surgery/fixtureLocation.ts","../src/surgery/insertCollection.ts","../src/surgery/insertFirstProperty.ts","../src/surgery/patchFixtureProperty.ts","../src/surgery/patchSingletonProperty.ts","../src/surgery/replaceFixture.ts","../src/surgery/setFixtureProperty.ts","../src/surgery/staticFixtureRule.ts","../test/apiCommand.test.ts","../test/authorizationUrl.test.ts","../test/autumnFetch.test.ts","../test/backfill.test.ts","../test/backfillInlineVariants.test.ts","../test/backfillSlug.test.ts","../test/backfillVariants.test.ts","../test/chooseConfigDir.test.ts","../test/cliTargetFlags.test.ts","../test/client.test.ts","../test/configPackageName.test.ts","../test/emitFixture.test.ts","../test/env.test.ts","../test/envWriter.test.ts","../test/init.test.ts","../test/keyless.test.ts","../test/legacyConfig.test.ts","../test/lintDocument.test.ts","../test/loadConfigNode.test.ts","../test/loadConfigV2.test.ts","../test/login.test.ts","../test/nodeNextTypes.test.ts","../test/plans.test.ts","../test/previewIsEmpty.test.ts","../test/prompt.test.ts","../test/pull.test.ts","../test/pullByReference.test.ts","../test/pullFieldLevel.test.ts","../test/pullOmitDefaults.test.ts","../test/pullPlans.test.ts","../test/pullStatesSlugs.test.ts","../test/pullTwoCollections.test.ts","../test/renameHint.test.ts","../test/renderPreview.test.ts","../test/renderSandboxes.test.ts","../test/renderSettings.test.ts","../test/reset.test.ts","../test/resolveCollectionTarget.test.ts","../test/resolveProject.test.ts","../test/resolveTarget.test.ts","../test/sandboxActions.test.ts","../test/sandboxKeyName.test.ts","../test/sandboxUse.test.ts","../test/settingsActions.test.ts","../test/settingsWire.test.ts","../test/skills.test.ts","../test/watchLauncher.test.ts","../test/wireDocument.test.ts","../test/helpers/targetFor.ts","../test/surgery/appendToCollection.test.ts","../test/surgery/deleteFixtureLiteral.test.ts","../test/surgery/deleteReference.test.ts","../test/surgery/findFixture.test.ts","../test/surgery/fixtureLocation.test.ts","../test/surgery/insertCollection.test.ts","../test/surgery/insertFirstProperty.test.ts","../test/surgery/patchFixtureProperty.test.ts","../test/surgery/patchSingletonProperty.test.ts","../test/surgery/replaceFixture.test.ts","../test/surgery/staticFixtureRule.test.ts"]}
1
+ {"version":"7.0.0-dev.20260511.1","root":["../src/bin.ts","../src/cli.ts","../src/index.ts","../src/version.ts","../src/actions/env.ts","../src/actions/login.ts","../src/actions/pull.ts","../src/actions/push.ts","../src/actions/api/callApi.ts","../src/actions/api/registerApiCommands.ts","../src/actions/env/fetchOrgInfo.ts","../src/actions/env/types/orgInfo.ts","../src/actions/init/runInit.ts","../src/actions/login/keyless.ts","../src/actions/pull/appendPlanVersionFixture.ts","../src/actions/pull/applyMappings.ts","../src/actions/pull/applyPreview.ts","../src/actions/pull/applySettingsPreview.ts","../src/actions/pull/changedFixtureKeys.ts","../src/actions/pull/listSourceFiles.ts","../src/actions/pull/locateFixture.ts","../src/actions/pull/resolveCollectionTarget.ts","../src/actions/pull/rewriteConfig.ts","../src/actions/pull/scaffoldConfig.ts","../src/actions/push/backfillInternalIds.ts","../src/actions/push/deprecatedFields.ts","../src/actions/reset/runReset.ts","../src/actions/sandbox/createSandbox.ts","../src/actions/sandbox/deleteSandbox.ts","../src/actions/sandbox/listSandboxes.ts","../src/actions/sandbox/useSandbox.ts","../src/actions/sandbox/withSandboxScopeHint.ts","../src/actions/sandbox/types/sandboxClient.ts","../src/actions/skills/ignoreBundledSkills.ts","../src/actions/skills/skills.ts","../src/auth/announceAuthorizationUrl.ts","../src/auth/buildAuthorizationUrl.ts","../src/auth/callbackPages.ts","../src/auth/createOrgApiKeys.ts","../src/auth/keyless.ts","../src/auth/oauthConfig.ts","../src/auth/runOAuthFlow.ts","../src/auth/browser/openSystemBrowser.ts","../src/auth/browser/tryOpenBrowser.ts","../src/auth/browser/watchLauncher.ts","../src/auth/types/browserOpener.ts","../src/auth/types/impersonationTokens.ts","../src/auth/types/oauthTokens.ts","../src/auth/types/orgApiKeys.ts","../src/config/configPackageName.ts","../src/config/legacyConfig.ts","../src/config/loadConfig.ts","../src/env/assertSandboxTarget.ts","../src/env/loadEnv.ts","../src/env/resolveTarget.ts","../src/env/sandboxKeyName.ts","../src/generated/apiRoutes.ts","../src/generated/client.ts","../src/generated/emit.ts","../src/generated/emitRuntime.ts","../src/generated/features.ts","../src/generated/labels.ts","../src/generated/licenses.ts","../src/generated/lintRules.ts","../src/generated/lintRuntime.ts","../src/generated/mappingAssignments.ts","../src/generated/plans.ts","../src/generated/referralPrograms.ts","../src/generated/rewards.ts","../src/generated/settings.ts","../src/generated/skills.ts","../src/generated/variants.ts","../src/generated/wire.ts","../src/http/autumnFetch.ts","../src/project/chooseConfigDir.ts","../src/project/resolveProject.ts","../src/project/rootMarker.ts","../src/prompt/prompt.ts","../src/prompt/select.ts","../src/render/renderEnv.ts","../src/render/renderPreview.ts","../src/render/renderSandboxes.ts","../src/render/stripTerminalControls.ts","../src/repo/findRepoRoot.ts","../src/surgery/appendPropertyEdit.ts","../src/surgery/appendToArray.ts","../src/surgery/appendToBinding.ts","../src/surgery/appendToCollection.ts","../src/surgery/appendToFixtureArray.ts","../src/surgery/arrayBinding.ts","../src/surgery/deleteFixtureLiteral.ts","../src/surgery/deleteReference.ts","../src/surgery/ensureBuilderImport.ts","../src/surgery/findFixture.ts","../src/surgery/fixtureEdit.ts","../src/surgery/fixtureLocation.ts","../src/surgery/insertCollection.ts","../src/surgery/insertFirstProperty.ts","../src/surgery/patchFixturePaths.ts","../src/surgery/patchFixtureProperty.ts","../src/surgery/patchSingletonProperty.ts","../src/surgery/readFixtureValue.ts","../src/surgery/replaceFixture.ts","../src/surgery/setFixtureProperty.ts","../src/surgery/staticFixtureRule.ts","../test/apiCommand.test.ts","../test/authorizationUrl.test.ts","../test/autumnFetch.test.ts","../test/backfill.test.ts","../test/backfillInlineVariants.test.ts","../test/backfillSlug.test.ts","../test/backfillVariants.test.ts","../test/chooseConfigDir.test.ts","../test/cliTargetFlags.test.ts","../test/client.test.ts","../test/configPackageName.test.ts","../test/emitFixture.test.ts","../test/env.test.ts","../test/envWriter.test.ts","../test/ignoreBundledSkills.test.ts","../test/init.test.ts","../test/keyless.test.ts","../test/legacyConfig.test.ts","../test/lintDocument.test.ts","../test/loadConfigNode.test.ts","../test/loadConfigV2.test.ts","../test/locateFixtureUnique.test.ts","../test/login.test.ts","../test/nodeNextTypes.test.ts","../test/patchFixturePaths.test.ts","../test/plans.test.ts","../test/previewIsEmpty.test.ts","../test/prompt.test.ts","../test/pull.test.ts","../test/pullByReference.test.ts","../test/pullFieldLevel.test.ts","../test/pullMappings.test.ts","../test/pullOmitDefaults.test.ts","../test/pullPlans.test.ts","../test/pullStatesSlugs.test.ts","../test/pullTwoCollections.test.ts","../test/readFixtureValue.test.ts","../test/renameHint.test.ts","../test/renderPreview.test.ts","../test/renderSandboxes.test.ts","../test/renderSettings.test.ts","../test/reset.test.ts","../test/resolveCollectionTarget.test.ts","../test/resolveProject.test.ts","../test/resolveTarget.test.ts","../test/sandboxActions.test.ts","../test/sandboxKeyName.test.ts","../test/sandboxUse.test.ts","../test/settingsActions.test.ts","../test/settingsWire.test.ts","../test/skills.test.ts","../test/watchLauncher.test.ts","../test/wireDocument.test.ts","../test/helpers/targetFor.ts","../test/surgery/appendToCollection.test.ts","../test/surgery/deleteFixtureLiteral.test.ts","../test/surgery/deleteReference.test.ts","../test/surgery/findFixture.test.ts","../test/surgery/fixtureLocation.test.ts","../test/surgery/insertCollection.test.ts","../test/surgery/insertFirstProperty.test.ts","../test/surgery/patchFixtureProperty.test.ts","../test/surgery/patchSingletonProperty.test.ts","../test/surgery/replaceFixture.test.ts","../test/surgery/staticFixtureRule.test.ts"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atmn",
3
- "version": "2.0.11",
3
+ "version": "2.0.13",
4
4
  "license": "MIT",
5
5
  "description": "The CLI for Autumn — define your pricing in code, sync it to Autumn, and keep everything in version control.",
6
6
  "bin": {
@@ -49,5 +49,5 @@
49
49
  "open": "10.2.0",
50
50
  "yaml": "2.9.0"
51
51
  },
52
- "gitHead": "b19c41f62894316db8ed1d5d6a87ad5f8c3f3798"
52
+ "gitHead": "56a30233085c57237f966558842ec13e17e3b2fc"
53
53
  }
@@ -29,6 +29,7 @@ import {
29
29
  runKeylessLogin,
30
30
  } from "../login/keyless";
31
31
  import { scaffoldConfig } from "../pull/scaffoldConfig";
32
+ import { ignoreBundledSkills } from "../skills/ignoreBundledSkills";
32
33
  import { installSkills, SKILLS_DIR_NAME } from "../skills/skills";
33
34
 
34
35
  /** The network, behind functions so a test can hand over fakes. */
@@ -385,6 +386,7 @@ export const runInit = async ({
385
386
 
386
387
  const skillsDir = join(configDir, SKILLS_DIR_NAME);
387
388
  const { written } = installSkills({ dir: skillsDir, write: () => {} });
389
+ ignoreBundledSkills({ repoRoot, configDir });
388
390
  prompter.write(
389
391
  `${done(`Skills: ${relative(repoRoot, skillsDir)}/${written.join(", ")}`)}\n`,
390
392
  );
@@ -0,0 +1,100 @@
1
+ import { COLLECTIONS, NESTED_FIXTURES } from "../../generated/emit";
2
+ import { resolveBranch } from "../../generated/emitRuntime";
3
+ import { mappingAssignments } from "../../generated/mappingAssignments";
4
+ import { patchFixturePaths } from "../../surgery/patchFixturePaths";
5
+ import { readFixtureValue } from "../../surgery/readFixtureValue";
6
+ import { locateFixture } from "./locateFixture";
7
+
8
+ export const applyMappings = ({
9
+ catalog,
10
+ configPath,
11
+ files,
12
+ }: {
13
+ catalog: Record<string, unknown>;
14
+ configPath: string;
15
+ files: Map<string, string>;
16
+ }): {
17
+ replaced: string[];
18
+ unlocated: { collection: string; id: string; action: string }[];
19
+ } => {
20
+ const replaced: string[] = [];
21
+ const unlocated: { collection: string; id: string; action: string }[] = [];
22
+ const builders = Object.values(NESTED_FIXTURES).map(({ builder }) => builder);
23
+ for (const [collection, collectionSpec] of Object.entries(COLLECTIONS)) {
24
+ const rows = catalog[collection];
25
+ if (!collectionSpec.pull || !Array.isArray(rows)) continue;
26
+ for (const entry of rows) {
27
+ const { spec, row } = resolveBranch({ spec: collectionSpec, row: entry });
28
+ const id = row[spec.responseIdField];
29
+ if (!spec.mappings || typeof id !== "string" || row.archived === true)
30
+ continue;
31
+ const key = spec.versioned ? `${id}@${row.versionSlug ?? "v1"}` : id;
32
+ const located = locateFixture({
33
+ configPath,
34
+ files,
35
+ builder: spec.builder,
36
+ idField: spec.idField,
37
+ id,
38
+ internalId:
39
+ typeof row.internalId === "string" ? row.internalId : undefined,
40
+ where: spec.versioned
41
+ ? [
42
+ {
43
+ field: "versionSlug",
44
+ equals:
45
+ typeof row.versionSlug === "string" ? row.versionSlug : "v1",
46
+ absentMeans: "v1",
47
+ },
48
+ ]
49
+ : undefined,
50
+ allowDynamic: true,
51
+ requireUnique: true,
52
+ });
53
+ if (!located) {
54
+ unlocated.push({
55
+ collection,
56
+ id: key,
57
+ action: "cannot locate the fixture to write processor mappings",
58
+ });
59
+ continue;
60
+ }
61
+ const planned = mappingAssignments({
62
+ projection: spec.mappings,
63
+ local: readFixtureValue({
64
+ node: located.node,
65
+ builders: [spec.builder, ...builders],
66
+ }),
67
+ remote: row,
68
+ });
69
+ if (planned.errors.length) {
70
+ unlocated.push(
71
+ ...planned.errors.map((action) => ({ collection, id: key, action })),
72
+ );
73
+ continue;
74
+ }
75
+ if (!planned.assignments.length) continue;
76
+ const patched = patchFixturePaths({
77
+ source: located.source,
78
+ builder: located.builder,
79
+ idField: located.idField,
80
+ id: located.id,
81
+ where: located.where,
82
+ builders,
83
+ assignments: planned.assignments,
84
+ });
85
+ if (!patched || patched.skipped.length) {
86
+ unlocated.push({
87
+ collection,
88
+ id: key,
89
+ action:
90
+ "cannot safely splice processor mappings into a computed or ambiguous value",
91
+ });
92
+ continue;
93
+ }
94
+ if (patched.source === located.source) continue;
95
+ files.set(located.file, patched.source);
96
+ replaced.push(key);
97
+ }
98
+ }
99
+ return { replaced, unlocated };
100
+ };
@@ -2,7 +2,7 @@ import type { SgNode } from "@ast-grep/napi";
2
2
  import {
3
3
  type FixtureConstraint,
4
4
  type FixtureShape,
5
- findFixture,
5
+ findFixtures,
6
6
  } from "../../surgery/findFixture";
7
7
 
8
8
  /** The file, its source, the node, and the lookup that found it — reuse the
@@ -35,6 +35,7 @@ export const locateFixture = ({
35
35
  internalId,
36
36
  where,
37
37
  allowDynamic = false,
38
+ requireUnique = false,
38
39
  }: {
39
40
  configPath: string;
40
41
  files: Map<string, string>;
@@ -44,6 +45,7 @@ export const locateFixture = ({
44
45
  internalId?: string | null;
45
46
  where?: FixtureConstraint[];
46
47
  allowDynamic?: boolean;
48
+ requireUnique?: boolean;
47
49
  }): LocatedFixture | null => {
48
50
  const others = [...files.keys()].filter((file) => file !== configPath);
49
51
  const ordered = [configPath, ...others];
@@ -59,20 +61,33 @@ export const locateFixture = ({
59
61
  ];
60
62
  const shapes = Array.isArray(builder) ? builder : [builder];
61
63
  for (const attempt of attempts) {
64
+ const matches = new Map<string, LocatedFixture>();
62
65
  for (const file of ordered) {
63
66
  const source = files.get(file);
64
67
  if (source === undefined) continue;
65
68
  for (const shape of shapes) {
66
- const node = findFixture({
69
+ const nodes = findFixtures({
67
70
  source,
68
71
  builder: shape,
69
72
  allowDynamic,
70
73
  ...attempt,
71
74
  });
72
- if (node !== null)
73
- return { file, source, node, builder: shape, ...attempt };
75
+ for (const node of nodes) {
76
+ const located = { file, source, node, builder: shape, ...attempt };
77
+ if (!requireUnique) return located;
78
+ const range = node.range();
79
+ const key = JSON.stringify([
80
+ file,
81
+ range.start.index,
82
+ range.end.index,
83
+ ]);
84
+ matches.set(key, located);
85
+ if (matches.size > 1) return null;
86
+ }
74
87
  }
75
88
  }
89
+ const match = matches.values().next().value;
90
+ if (match !== undefined) return match;
76
91
  }
77
92
  return null;
78
93
  };
@@ -16,6 +16,7 @@ import { resolveProject } from "../project/resolveProject";
16
16
  import { writeRootMarker } from "../project/rootMarker";
17
17
  import { createPrompter, done, type Prompter } from "../prompt/prompt";
18
18
  import type { SettingsPreview } from "../render/renderPreview";
19
+ import { applyMappings } from "./pull/applyMappings";
19
20
  import { applyPreview, type PreviewEntry } from "./pull/applyPreview";
20
21
  import { applySettingsPreview } from "./pull/applySettingsPreview";
21
22
  import { listSourceFiles } from "./pull/listSourceFiles";
@@ -341,6 +342,27 @@ export const runPull = async ({
341
342
  );
342
343
  }
343
344
 
345
+ if (includeMappings) {
346
+ const managedCatalog = Object.fromEntries(
347
+ Object.entries(COLLECTIONS)
348
+ .filter(
349
+ ([, spec]) =>
350
+ spec.wireKey !== undefined && wire[spec.wireKey] !== undefined,
351
+ )
352
+ .map(([collection]) => [collection, catalogRows[collection]]),
353
+ );
354
+ const mapped = applyMappings({
355
+ catalog: managedCatalog,
356
+ configPath,
357
+ files,
358
+ });
359
+ unlocated.push(...mapped.unlocated);
360
+ for (const id of mapped.replaced) {
361
+ if (!replaced.includes(id) && !appended.includes(id)) replaced.push(id);
362
+ lines.push(`↳ wrote processor mappings into ${id}`);
363
+ }
364
+ }
365
+
344
366
  // A fixture that is not a plain literal cannot be edited in place; saying
345
367
  // so before writing anything beats a half-applied pull.
346
368
  if (unlocated.length > 0) throw new UnlocatableFixturesError({ unlocated });
@@ -0,0 +1,32 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { isAbsolute, join, relative, sep } from "node:path";
3
+ import { SKILLS_DIR_NAME } from "./skills";
4
+
5
+ export const ignoreBundledSkills = ({
6
+ repoRoot,
7
+ configDir,
8
+ }: {
9
+ repoRoot: string;
10
+ configDir: string;
11
+ }): void => {
12
+ const path = relative(repoRoot, join(configDir, SKILLS_DIR_NAME));
13
+ if (isAbsolute(path) || path === ".." || path.startsWith(`..${sep}`)) return;
14
+ if (/[\r\n]/.test(path)) return;
15
+ const pattern = `/${path
16
+ .split(sep)
17
+ .join("/")
18
+ .replace(/[\\*?[\] ]/g, "\\$&")}/`;
19
+ const ignorePath = join(repoRoot, ".gitignore");
20
+ const contents = existsSync(ignorePath)
21
+ ? readFileSync(ignorePath, "utf8")
22
+ : "";
23
+ if (contents.split(/\r?\n/).includes(pattern)) return;
24
+ const newline = contents.includes("\r\n") ? "\r\n" : "\n";
25
+ const separator =
26
+ contents.length > 0 && !contents.endsWith("\n") ? newline : "";
27
+ writeFileSync(
28
+ ignorePath,
29
+ `${contents}${separator}${pattern}${newline}`,
30
+ "utf8",
31
+ );
32
+ };
package/src/cli.ts CHANGED
@@ -21,6 +21,7 @@ import { runSandboxDelete } from "./actions/sandbox/deleteSandbox";
21
21
  import { runSandboxList } from "./actions/sandbox/listSandboxes";
22
22
  import { runSandboxUse } from "./actions/sandbox/useSandbox";
23
23
  import { withSandboxScopeHint } from "./actions/sandbox/withSandboxScopeHint";
24
+ import { ignoreBundledSkills } from "./actions/skills/ignoreBundledSkills";
24
25
  import {
25
26
  installSkills,
26
27
  linkSkills,
@@ -431,6 +432,8 @@ Linking a keyless org to an account:
431
432
  async (options: { dir?: string; link?: boolean }, command: Command) => {
432
433
  const dir = skillsDirOf({ command, dir: options.dir });
433
434
  installSkills({ dir, write: (text) => process.stdout.write(text) });
435
+ if (options.dir === undefined)
436
+ ignoreBundledSkills(projectOf({ command }));
434
437
  if (options.link === true)
435
438
  await linkSkills({
436
439
  dir,
@@ -449,6 +452,8 @@ Linking a keyless org to an account:
449
452
  .action((options: { dir?: string }, command: Command) => {
450
453
  const dir = skillsDirOf({ command, dir: options.dir });
451
454
  updateSkills({ dir, write: (text) => process.stdout.write(text) });
455
+ if (options.dir === undefined)
456
+ ignoreBundledSkills(projectOf({ command }));
452
457
  });
453
458
 
454
459
  program
@@ -299,6 +299,30 @@ export const API_ROUTES: readonly ApiRoute[] = [
299
299
  },
300
300
  ],
301
301
  },
302
+ {
303
+ group: "customers",
304
+ method: "advance_test_clock",
305
+ path: "/v1/customers.advance_test_clock",
306
+ description:
307
+ "Advance a customer's Stripe test clock to a future time in milliseconds. Only Stripe test-mode customers with a test clock are supported. Advancement is asynchronous; Stripe enforces clock status and advancement limits.",
308
+ body: "object",
309
+ fields: [
310
+ {
311
+ name: "customer_id",
312
+ type: "string",
313
+ required: true,
314
+ description:
315
+ "The ID of the customer whose Stripe test clock to advance.",
316
+ },
317
+ {
318
+ name: "frozen_time",
319
+ type: "number",
320
+ required: true,
321
+ description:
322
+ "Target time as a Unix timestamp in milliseconds. Rounded down to whole seconds; must be later than the current clock time.",
323
+ },
324
+ ],
325
+ },
302
326
  {
303
327
  group: "plans",
304
328
  method: "create",
@@ -1072,30 +1096,6 @@ export const API_ROUTES: readonly ApiRoute[] = [
1072
1096
  },
1073
1097
  ],
1074
1098
  },
1075
- {
1076
- group: "billing",
1077
- method: "advance_test_clock",
1078
- path: "/v1/billing.advance_test_clock",
1079
- description:
1080
- "Advance a customer's Stripe test clock to a future time in milliseconds. Only Stripe test-mode customers with a test clock are supported. Advancement is asynchronous; Stripe enforces clock status and advancement limits.",
1081
- body: "object",
1082
- fields: [
1083
- {
1084
- name: "customer_id",
1085
- type: "string",
1086
- required: true,
1087
- description:
1088
- "The ID of the customer whose Stripe test clock to advance.",
1089
- },
1090
- {
1091
- name: "frozen_time",
1092
- type: "number",
1093
- required: true,
1094
- description:
1095
- "Target time as a Unix timestamp in milliseconds. Rounded down to whole seconds; must be later than the current clock time.",
1096
- },
1097
- ],
1098
- },
1099
1099
  {
1100
1100
  group: "billing",
1101
1101
  method: "create_schedule",
@@ -5,6 +5,7 @@ import type { CollectionSpec, SingletonSpec } from "./emitRuntime";
5
5
 
6
6
  export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
7
7
  features: {
8
+ wireKey: "features",
8
9
  builder: "feature",
9
10
  idField: "featureId",
10
11
  responseIdField: "id",
@@ -80,11 +81,13 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
80
81
  "providerMarkups.*.markup",
81
82
  "type",
82
83
  ],
84
+ mappings: { properties: { processors: { mapping: true } } },
83
85
  defaults: {},
84
86
  pull: true,
85
87
  deprecated: [],
86
88
  },
87
89
  plans: {
90
+ wireKey: "plans",
88
91
  builder: "plan",
89
92
  idField: "planId",
90
93
  responseIdField: "id",
@@ -865,6 +868,43 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
865
868
  "variants.versionSlug",
866
869
  "versionSlug",
867
870
  ],
871
+ mappings: {
872
+ properties: {
873
+ processors: { mapping: true },
874
+ price: { properties: { processors: { mapping: true } } },
875
+ items: {
876
+ items: {
877
+ properties: {
878
+ price: { properties: { processors: { mapping: true } } },
879
+ },
880
+ },
881
+ identity: {
882
+ responseField: "mappingIdentity",
883
+ components: [
884
+ { paths: ["featureId"], default: "" },
885
+ { paths: ["price.billingMethod"], default: "" },
886
+ { paths: ["price.interval", "reset.interval"], default: "" },
887
+ {
888
+ paths: ["price.intervalCount", "reset.intervalCount"],
889
+ default: "",
890
+ defaultWhen: { component: 2, value: 1 },
891
+ },
892
+ ],
893
+ },
894
+ },
895
+ variants: {
896
+ items: {
897
+ properties: {
898
+ processors: { mapping: true, sourcePath: ["plan", "processors"] },
899
+ },
900
+ },
901
+ identity: {
902
+ responseField: "mappingIdentity",
903
+ components: [{ paths: ["variantPlanId"], default: "" }],
904
+ },
905
+ },
906
+ },
907
+ },
868
908
  defaults: {
869
909
  addOn: false,
870
910
  autoEnable: false,
@@ -961,6 +1001,7 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
961
1001
  ],
962
1002
  },
963
1003
  rewards: {
1004
+ wireKey: "rewards",
964
1005
  builder: "reward",
965
1006
  idField: "id",
966
1007
  responseIdField: "id",
@@ -1103,6 +1144,7 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
1103
1144
  ],
1104
1145
  },
1105
1146
  referralPrograms: {
1147
+ wireKey: "referral_programs",
1106
1148
  builder: "referralProgram",
1107
1149
  idField: "id",
1108
1150
  responseIdField: "id",
@@ -1,13 +1,11 @@
1
1
  // Copied by @autumn/atmn-generator from packages/atmn-generator/src/emit/runtime/emitFixture.ts.
2
2
  // Do not edit — change that file and run `bun generate` instead.
3
3
 
4
- /**
5
- * Copied verbatim into the CLI by the generator, so this file imports nothing:
6
- * a pulled server row becomes fixture source here, in the exact shape the
7
- * surgery module splices into the user's config.
8
- */
4
+ import type { MappingProjection } from "./mappingAssignments";
9
5
 
10
6
  export type CollectionSpec = {
7
+ readonly wireKey?: string;
8
+ readonly mappings?: MappingProjection;
11
9
  readonly builder: string;
12
10
  readonly idField: string;
13
11
  readonly responseIdField: string;