atmn 1.1.25 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +120 -0
  2. package/dist/bin.js +23318 -0
  3. package/dist/index.js +2946 -0
  4. package/dist/tsconfig.tsbuildinfo +1 -1
  5. package/package.json +28 -74
  6. package/src/actions/api/callApi.ts +280 -0
  7. package/src/actions/api/registerApiCommands.ts +121 -0
  8. package/src/actions/env/fetchOrgInfo.ts +32 -0
  9. package/src/actions/env/types/orgInfo.ts +18 -0
  10. package/src/actions/env.ts +94 -0
  11. package/src/actions/init/runInit.ts +401 -0
  12. package/src/actions/login/keyless.ts +135 -0
  13. package/src/actions/login.ts +144 -0
  14. package/src/actions/pull/appendPlanVersionFixture.ts +373 -0
  15. package/src/actions/pull/applyPreview.ts +553 -0
  16. package/src/actions/pull/applySettingsPreview.ts +114 -0
  17. package/src/actions/pull/changedFixtureKeys.ts +88 -0
  18. package/src/actions/pull/listSourceFiles.ts +29 -0
  19. package/src/actions/pull/locateFixture.ts +78 -0
  20. package/src/actions/pull/resolveCollectionTarget.ts +198 -0
  21. package/src/actions/pull/rewriteConfig.ts +57 -0
  22. package/src/actions/pull/scaffoldConfig.ts +118 -0
  23. package/src/actions/pull.ts +399 -0
  24. package/src/actions/push/backfillInternalIds.ts +394 -0
  25. package/src/actions/push/deprecatedFields.ts +55 -0
  26. package/src/actions/push.ts +294 -0
  27. package/src/actions/reset/runReset.ts +58 -0
  28. package/src/actions/sandbox/createSandbox.ts +83 -0
  29. package/src/actions/sandbox/deleteSandbox.ts +91 -0
  30. package/src/actions/sandbox/listSandboxes.ts +28 -0
  31. package/src/actions/sandbox/types/sandboxClient.ts +16 -0
  32. package/src/actions/sandbox/useSandbox.ts +157 -0
  33. package/src/actions/sandbox/withSandboxScopeHint.ts +27 -0
  34. package/src/actions/skills/skills.ts +246 -0
  35. package/src/auth/announceAuthorizationUrl.ts +26 -0
  36. package/src/auth/browser/openSystemBrowser.ts +7 -0
  37. package/src/auth/browser/tryOpenBrowser.ts +17 -0
  38. package/src/auth/browser/watchLauncher.ts +46 -0
  39. package/src/auth/buildAuthorizationUrl.ts +36 -0
  40. package/src/auth/callbackPages.ts +126 -0
  41. package/src/auth/createOrgApiKeys.ts +46 -0
  42. package/src/auth/keyless.ts +119 -0
  43. package/src/auth/oauthConfig.ts +63 -0
  44. package/src/auth/runOAuthFlow.ts +230 -0
  45. package/src/auth/types/browserOpener.ts +5 -0
  46. package/src/auth/types/impersonationTokens.ts +23 -0
  47. package/src/auth/types/oauthTokens.ts +13 -0
  48. package/src/auth/types/orgApiKeys.ts +6 -0
  49. package/src/bin.ts +9 -0
  50. package/src/cli.ts +648 -0
  51. package/src/config/configPackageName.ts +9 -0
  52. package/src/config/legacyConfig.ts +25 -0
  53. package/src/config/loadConfig.ts +231 -0
  54. package/src/env/assertSandboxTarget.ts +20 -0
  55. package/src/env/loadEnv.ts +184 -0
  56. package/src/env/resolveTarget.ts +134 -0
  57. package/src/env/sandboxKeyName.ts +18 -0
  58. package/src/generated/apiRoutes.ts +3937 -0
  59. package/src/generated/client.ts +52579 -0
  60. package/src/generated/emit.ts +1188 -0
  61. package/src/generated/emitRuntime.ts +522 -0
  62. package/src/generated/features.ts +146 -0
  63. package/src/generated/labels.ts +29 -0
  64. package/src/generated/licenses.ts +292 -0
  65. package/src/generated/lintRules.ts +2247 -0
  66. package/src/generated/lintRuntime.ts +865 -0
  67. package/src/generated/plans.ts +1653 -0
  68. package/src/generated/referralPrograms.ts +22 -0
  69. package/src/generated/rewards.ts +58 -0
  70. package/src/generated/settings.ts +21 -0
  71. package/src/generated/skills.ts +305 -0
  72. package/src/generated/variants.ts +949 -0
  73. package/src/generated/wire.ts +334 -0
  74. package/src/http/autumnFetch.ts +30 -0
  75. package/src/index.ts +20 -0
  76. package/src/project/chooseConfigDir.ts +41 -0
  77. package/src/project/resolveProject.ts +115 -0
  78. package/src/project/rootMarker.ts +40 -0
  79. package/src/prompt/prompt.ts +186 -0
  80. package/src/prompt/select.ts +162 -0
  81. package/src/render/renderEnv.ts +77 -0
  82. package/src/render/renderPreview.ts +945 -0
  83. package/src/render/renderSandboxes.ts +92 -0
  84. package/src/render/stripTerminalControls.ts +19 -0
  85. package/src/repo/findRepoRoot.ts +79 -0
  86. package/src/surgery/appendPropertyEdit.ts +67 -0
  87. package/src/surgery/appendToArray.ts +87 -0
  88. package/src/surgery/appendToBinding.ts +19 -0
  89. package/src/surgery/appendToCollection.ts +40 -0
  90. package/src/surgery/appendToFixtureArray.ts +71 -0
  91. package/src/surgery/arrayBinding.ts +30 -0
  92. package/src/surgery/deleteFixtureLiteral.ts +81 -0
  93. package/src/surgery/deleteReference.ts +48 -0
  94. package/src/surgery/ensureBuilderImport.ts +65 -0
  95. package/src/surgery/findFixture.ts +238 -0
  96. package/src/surgery/fixtureEdit.ts +156 -0
  97. package/src/surgery/fixtureLocation.ts +32 -0
  98. package/src/surgery/insertCollection.ts +86 -0
  99. package/src/surgery/insertFirstProperty.ts +73 -0
  100. package/src/surgery/patchFixtureProperty.ts +152 -0
  101. package/src/surgery/patchSingletonProperty.ts +221 -0
  102. package/src/surgery/replaceFixture.ts +28 -0
  103. package/src/surgery/setFixtureProperty.ts +55 -0
  104. package/src/surgery/staticFixtureRule.ts +48 -0
  105. package/src/version.ts +5 -0
  106. package/dist/cli.js +0 -146296
  107. package/dist/compose/index.js +0 -122
  108. package/dist/src/compose/builders/builderFunctions.d.ts +0 -84
  109. package/dist/src/compose/builders/rewardFunctions.d.ts +0 -5
  110. package/dist/src/compose/builders/variantFunctions.d.ts +0 -2
  111. package/dist/src/compose/index.d.ts +0 -19
  112. package/dist/src/compose/models/featureModels.d.ts +0 -262
  113. package/dist/src/compose/models/index.d.ts +0 -3
  114. package/dist/src/compose/models/planModels.d.ts +0 -562
  115. package/dist/src/compose/models/rewardModels.d.ts +0 -52
  116. package/dist/src/compose/models/variantModels.d.ts +0 -34
  117. package/readme.md +0 -186
@@ -1 +1 @@
1
- {"version":"7.0.0-dev.20260511.1","root":["../src/cli.tsx","../src/constants.ts","../src/commands/auth/command.ts","../src/commands/auth/constants.ts","../src/commands/auth/oauth.ts","../src/commands/config/command.ts","../src/commands/customers/command.tsx","../src/commands/customers/headless.ts","../src/commands/customers/index.ts","../src/commands/events/command.tsx","../src/commands/events/headless.ts","../src/commands/events/index.ts","../src/commands/events-aggregate-test/command.ts","../src/commands/events-aggregate-test/index.ts","../src/commands/features/command.tsx","../src/commands/features/headless.ts","../src/commands/features/index.ts","../src/commands/nuke/backup.ts","../src/commands/nuke/deletions.ts","../src/commands/nuke/legacyNuke.ts","../src/commands/nuke/types.ts","../src/commands/nuke/validation.ts","../src/commands/preview/index.ts","../src/commands/preview/previewPlan.ts","../src/commands/products/command.tsx","../src/commands/products/headless.ts","../src/commands/products/index.ts","../src/commands/pull/index.ts","../src/commands/pull/mergeEnvironments.ts","../src/commands/pull/pull.ts","../src/commands/pull/pullFromEnvironment.ts","../src/commands/pull/sdkTypes.ts","../src/commands/pull/types.ts","../src/commands/pull/writeConfig.ts","../src/commands/push/headless.ts","../src/commands/push/index.ts","../src/commands/push/prompts.ts","../src/commands/push/push.ts","../src/commands/push/types.ts","../src/commands/push/validate.ts","../src/commands/push/variantPropagation.ts","../src/commands/test-diff/command.ts","../src/commands/test-diff/index.ts","../src/commands/test-template/command.tsx","../src/compose/index.ts","../src/compose/builders/builderFunctions.ts","../src/compose/builders/rewardFunctions.ts","../src/compose/builders/variantFunctions.ts","../src/compose/models/featureModels.ts","../src/compose/models/index.ts","../src/compose/models/planModels.ts","../src/compose/models/rewardModels.ts","../src/compose/models/variantModels.ts","../src/lib/utils.ts","../src/lib/version.ts","../src/lib/writeEmptyConfig.ts","../src/lib/animation/explosion.ts","../src/lib/api/client.ts","../src/lib/api/endpoints/catalog.ts","../src/lib/api/endpoints/customers.ts","../src/lib/api/endpoints/events.ts","../src/lib/api/endpoints/features.ts","../src/lib/api/endpoints/index.ts","../src/lib/api/endpoints/organization.ts","../src/lib/api/endpoints/plans.ts","../src/lib/api/endpoints/rewards.ts","../src/lib/api/types/feature.ts","../src/lib/api/types/index.ts","../src/lib/api/types/organization.ts","../src/lib/api/types/plan.ts","../src/lib/api/types/planItem.ts","../src/lib/auth/headlessAuthRecovery.ts","../src/lib/config/loadConfig.ts","../src/lib/constants/templates.ts","../src/lib/constants/templates/index.ts","../src/lib/constants/templates/linear.config.ts","../src/lib/constants/templates/openai.config.ts","../src/lib/constants/templates/railway.config.ts","../src/lib/constants/templates/t3chat.config.ts","../src/lib/env/backendUrl.ts","../src/lib/env/cliContext.ts","../src/lib/env/detect.ts","../src/lib/env/dotenv.ts","../src/lib/env/index.ts","../src/lib/env/keys.ts","../src/lib/headless/CustomersController.ts","../src/lib/headless/FeaturesController.ts","../src/lib/headless/PlansController.ts","../src/lib/headless/index.ts","../src/lib/headless/types.ts","../src/lib/hooks/index.ts","../src/lib/hooks/useAgentSetup.ts","../src/lib/hooks/useAuthRecovery.ts","../src/lib/hooks/useClipboard.ts","../src/lib/hooks/useConfigCounts.ts","../src/lib/hooks/useCreateGuides.ts","../src/lib/hooks/useCreateSkills.ts","../src/lib/hooks/useCustomerExpanded.ts","../src/lib/hooks/useCustomerNavigation.ts","../src/lib/hooks/useCustomers.ts","../src/lib/hooks/useEnvironmentStore.ts","../src/lib/hooks/useEvents.ts","../src/lib/hooks/useEventsAggregate.ts","../src/lib/hooks/useEventsAggregateApi.ts","../src/lib/hooks/useEventsFilter.ts","../src/lib/hooks/useFeatures.ts","../src/lib/hooks/useHasCustomers.ts","../src/lib/hooks/useHeadlessAuth.ts","../src/lib/hooks/useListNavigation.ts","../src/lib/hooks/useLogin.ts","../src/lib/hooks/useNuke.ts","../src/lib/hooks/useNukeData.ts","../src/lib/hooks/useOrganization.ts","../src/lib/hooks/usePlans.ts","../src/lib/hooks/usePull.ts","../src/lib/hooks/usePush.ts","../src/lib/hooks/useTerminalSize.ts","../src/lib/hooks/useVisibleRowCount.ts","../src/lib/hooks/useWriteTemplateConfig.ts","../src/lib/transforms/index.ts","../src/lib/transforms/multiCurrency.test.ts","../src/lib/transforms/apiToSdk/Transformer.test.ts","../src/lib/transforms/apiToSdk/Transformer.ts","../src/lib/transforms/apiToSdk/feature.ts","../src/lib/transforms/apiToSdk/helpers.ts","../src/lib/transforms/apiToSdk/index.ts","../src/lib/transforms/apiToSdk/plan.ts","../src/lib/transforms/apiToSdk/planItem.ts","../src/lib/transforms/apiToSdk/reward.ts","../src/lib/transforms/inPlaceUpdate/index.ts","../src/lib/transforms/inPlaceUpdate/parseConfig.ts","../src/lib/transforms/inPlaceUpdate/updateConfig.ts","../src/lib/transforms/sdkToApi/feature.ts","../src/lib/transforms/sdkToApi/index.ts","../src/lib/transforms/sdkToApi/plan.ts","../src/lib/transforms/sdkToApi/reward.ts","../src/lib/transforms/sdkToCode/configFile.ts","../src/lib/transforms/sdkToCode/feature.ts","../src/lib/transforms/sdkToCode/helpers.test.ts","../src/lib/transforms/sdkToCode/helpers.ts","../src/lib/transforms/sdkToCode/imports.ts","../src/lib/transforms/sdkToCode/index.ts","../src/lib/transforms/sdkToCode/plan.ts","../src/lib/transforms/sdkToCode/planItem.ts","../src/lib/transforms/sdkToCode/reward.ts","../src/lib/transforms/sdkToCode/variant.ts","../src/lib/utils/index.ts","../src/lib/utils/monorepo.ts","../src/prompts/skills/autumn-billing-page.ts","../src/prompts/skills/autumn-gating.ts","../src/prompts/skills/autumn-modelling-pricing-plans.ts","../src/prompts/skills/autumn-setup.ts","../src/prompts/skills/index.ts","../src/views/App.tsx","../src/views/html/oauth-callback.ts","../src/views/react/test-agent.tsx","../src/views/react/components/AuthRecoveryBoundary.tsx","../src/views/react/components/Card.tsx","../src/views/react/components/KeyValue.tsx","../src/views/react/components/LoadingText.tsx","../src/views/react/components/MultiSelect.tsx","../src/views/react/components/ProgressBar.tsx","../src/views/react/components/PromptCard.tsx","../src/views/react/components/SelectMenu.tsx","../src/views/react/components/StatusLine.tsx","../src/views/react/components/StatusRow.tsx","../src/views/react/components/StepHeader.tsx","../src/views/react/components/index.ts","../src/views/react/components/providers/CardWidthContext.tsx","../src/views/react/components/providers/QueryProvider.tsx","../src/views/react/components/providers/index.ts","../src/views/react/customers/CustomersView.tsx","../src/views/react/customers/types.ts","../src/views/react/customers/components/CustomerRow.tsx","../src/views/react/customers/components/CustomerSheet.tsx","../src/views/react/customers/components/CustomersTable.tsx","../src/views/react/customers/components/EmptyState.tsx","../src/views/react/customers/components/ErrorState.tsx","../src/views/react/customers/components/KeybindHints.tsx","../src/views/react/customers/components/LoadingState.tsx","../src/views/react/customers/components/SearchInput.tsx","../src/views/react/customers/components/TitleBar.tsx","../src/views/react/customers/components/index.ts","../src/views/react/customers/components/sections/BalancesSection.tsx","../src/views/react/customers/components/sections/EntitiesSection.tsx","../src/views/react/customers/components/sections/InvoicesSection.tsx","../src/views/react/customers/components/sections/ReferralsSection.tsx","../src/views/react/customers/components/sections/RewardsSection.tsx","../src/views/react/customers/components/sections/SubscriptionsSection.tsx","../src/views/react/customers/components/sections/index.ts","../src/views/react/events/EventsView.tsx","../src/views/react/events/index.ts","../src/views/react/events/components/EventSheet.tsx","../src/views/react/events/components/EventsAggregateView.tsx","../src/views/react/events/components/EventsFilterSheet.tsx","../src/views/react/events/components/index.ts","../src/views/react/features/FeaturesView.tsx","../src/views/react/features/index.ts","../src/views/react/features/components/FeatureSheet.tsx","../src/views/react/features/components/index.ts","../src/views/react/init/HeadlessInitFlow.tsx","../src/views/react/init/InitFlow.tsx","../src/views/react/init/steps/AgentStep.tsx","../src/views/react/init/steps/AuthStep.tsx","../src/views/react/init/steps/ConfigStep.tsx","../src/views/react/init/steps/HandoffStep.tsx","../src/views/react/init/steps/PathInputStep.tsx","../src/views/react/init/steps/StripeStep.tsx","../src/views/react/login/LoginView.tsx","../src/views/react/nuke/InlineNukeFlow.tsx","../src/views/react/nuke/NukeAnimation.tsx","../src/views/react/nuke/NukeView.tsx","../src/views/react/nuke/components/BackupPrompt.tsx","../src/views/react/nuke/components/ConfirmScreen.tsx","../src/views/react/nuke/components/DeletionProgress.tsx","../src/views/react/nuke/components/FinalSummary.tsx","../src/views/react/nuke/components/SuccessScreen.tsx","../src/views/react/nuke/components/WarningScreen.tsx","../src/views/react/preview/PlanPreviewCard.tsx","../src/views/react/preview/PreviewView.tsx","../src/views/react/preview/index.ts","../src/views/react/primitives/index.ts","../src/views/react/primitives/input/SearchInput.tsx","../src/views/react/primitives/input/index.ts","../src/views/react/primitives/layout/BottomBar.tsx","../src/views/react/primitives/layout/ListViewLayout.tsx","../src/views/react/primitives/layout/SplitPane.tsx","../src/views/react/primitives/layout/TitleBar.tsx","../src/views/react/primitives/layout/index.ts","../src/views/react/primitives/sheet/DetailSheet.tsx","../src/views/react/primitives/sheet/SheetSection.tsx","../src/views/react/primitives/sheet/index.ts","../src/views/react/primitives/states/EmptyState.tsx","../src/views/react/primitives/states/ErrorState.tsx","../src/views/react/primitives/states/LoadingState.tsx","../src/views/react/primitives/states/index.ts","../src/views/react/primitives/table/DataTable.tsx","../src/views/react/primitives/table/TableRow.tsx","../src/views/react/primitives/table/index.ts","../src/views/react/primitives/utils/formatDate.ts","../src/views/react/primitives/utils/index.ts","../src/views/react/primitives/utils/pagination.ts","../src/views/react/primitives/utils/truncate.ts","../src/views/react/products/ProductsView.tsx","../src/views/react/products/index.ts","../src/views/react/products/components/ProductSheet.tsx","../src/views/react/products/components/index.ts","../src/views/react/pull/Pull.tsx","../src/views/react/pull/components/FeatureRow.tsx","../src/views/react/pull/components/FileRow.tsx","../src/views/react/pull/components/PlanRow.tsx","../src/views/react/pull/components/index.ts","../src/views/react/push/Push.tsx","../src/views/react/push/index.ts","../src/views/react/push/components/CompletionMessage.tsx","../src/views/react/push/components/ConfigResourcesPromptCard.tsx","../src/views/react/push/components/ErrorCard.tsx","../src/views/react/push/components/FeaturesCard.tsx","../src/views/react/push/components/NoChangesCard.tsx","../src/views/react/push/components/OrgCard.tsx","../src/views/react/push/components/OverviewCard.tsx","../src/views/react/push/components/PlansCard.tsx","../src/views/react/push/components/PushPromptCard.tsx","../src/views/react/push/components/index.ts","../src/views/react/template/TemplateSelector.tsx","../src/views/react/template2/Badge.tsx","../src/views/react/template2/PlanCard.tsx","../src/views/react/template2/TemplateRow.tsx","../src/views/react/template2/TemplateSelector2.tsx","../src/views/react/template2/data.ts","../src/views/react/template2/index.ts","../test/types/reward.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/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"]}
package/package.json CHANGED
@@ -1,9 +1,20 @@
1
1
  {
2
2
  "name": "atmn",
3
- "version": "1.1.25",
3
+ "version": "2.0.1",
4
4
  "license": "MIT",
5
+ "description": "The CLI for Autumn — define your pricing in code, sync it to Autumn, and keep everything in version control.",
5
6
  "bin": {
6
- "atmn": "dist/cli.js"
7
+ "atmn": "dist/bin.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "types": "src/index.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./src/index.ts",
14
+ "bun": "./src/index.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ }
7
18
  },
8
19
  "repository": {
9
20
  "type": "git",
@@ -11,89 +22,32 @@
11
22
  "directory": "packages/atmn"
12
23
  },
13
24
  "homepage": "https://docs.useautumn.com/api-reference/cli/getting-started",
14
- "main": "dist/compose/index.js",
15
- "types": "dist/src/compose/index.d.ts",
16
- "exports": {
17
- ".": {
18
- "types": "./dist/src/compose/index.d.ts",
19
- "import": "./dist/compose/index.js",
20
- "default": "./dist/compose/index.js"
21
- },
22
- "./skills": {
23
- "types": "./src/prompts/skills/index.ts",
24
- "import": "./src/prompts/skills/index.ts",
25
- "default": "./src/prompts/skills/index.ts"
26
- }
27
- },
28
25
  "type": "module",
29
26
  "engines": {
30
- "node": ">=16"
27
+ "node": ">=20"
31
28
  },
32
29
  "scripts": {
33
30
  "ts": "bunx tsgo --build --noEmit",
34
31
  "build": "bun run bun.config.ts",
35
- "dev": "nodemon -e ts,tsx --watch src --ignore dist --exec \"bun run bun.config.ts\"",
36
- "dev:bun": "bun run dev.ts",
37
- "test": "bun test test/*.test.ts test/auth test/codegen test/nuke test/pull test/push test/workflow",
38
- "test:integration": "echo 'deprecated: v1 atmn integration — see packages/atmn/test/integration/DEPRECATED.md' && exit 0",
39
- "test:integration:cli": "echo 'deprecated: v1 atmn integration — see packages/atmn/test/integration/DEPRECATED.md' && exit 0",
40
- "test:unit": "bun test test/codegen",
41
- "test:watch": "bun test --watch",
42
- "test2": "prettier --check . && xo && ava",
43
- "test-cli": "node --trace-deprecation -- ./dist/cli.js"
32
+ "dev": "bun scripts/watchBuild.ts",
33
+ "test": "bun test test",
34
+ "prepack": "bun run build"
44
35
  },
45
36
  "files": [
46
37
  "dist",
38
+ "src",
47
39
  "package.json",
48
40
  "README.md"
49
41
  ],
50
42
  "dependencies": {
51
- "@inquirer/prompts": "^7.6.0",
52
- "@mishieck/ink-titled-box": "^0.3.0",
53
- "@tanstack/react-query": "^5.90.17",
54
- "@types/prettier": "^3.0.0",
55
- "arctic": "^3.7.0",
56
- "axios": "^1.10.0",
57
- "cfonts": "^3.3.1",
58
- "chalk": "^5.2.0",
59
- "clipboardy": "^5.0.2",
60
- "commander": "^14.0.0",
61
- "dotenv": "^17.2.0",
62
- "ervy": "^1.0.7",
63
- "ink": "^6.6.0",
64
- "ink-big-text": "^2.0.0",
65
- "ink-chart": "^0.1.1",
66
- "ink-confirm-input": "^2.0.0",
67
- "ink-scroll-list": "^0.4.1",
68
- "ink-scroll-view": "^0.3.5",
69
- "ink-select-input": "^6.2.0",
70
- "ink-spinner": "^5.0.0",
71
- "ink-table": "^3.1.0",
72
- "ink-text-input": "^6.0.0",
73
- "inquirer": "^12.7.0",
74
- "jiti": "^2.4.2",
75
- "open": "^10.1.2",
76
- "prettier": "^3.6.2",
77
- "react": "^19.2.3",
78
- "yocto-spinner": "^1.0.0",
79
- "zod": "^4.0.0",
80
- "conf": "^13.0.1"
81
- },
82
- "ava": {
83
- "extensions": {
84
- "ts": "module",
85
- "tsx": "module"
86
- },
87
- "nodeArguments": [
88
- "--loader=ts-node/esm"
89
- ]
90
- },
91
- "xo": {
92
- "extends": "xo-react",
93
- "prettier": true,
94
- "rules": {
95
- "react/prop-types": "off"
96
- }
97
- },
98
- "prettier": "@vdemedes/prettier-config"
43
+ "@ast-grep/napi": "0.45.3",
44
+ "arctic": "3.7.0",
45
+ "chalk": "5.6.2",
46
+ "commander": "14.0.3",
47
+ "dotenv": "16.6.1",
48
+ "jiti": "2.7.0",
49
+ "open": "10.2.0",
50
+ "yaml": "2.9.0"
51
+ },
52
+ "gitHead": "5a548945bb2a7bec37404428767108467915449d"
99
53
  }
@@ -0,0 +1,280 @@
1
+ import type { ApiField, ApiRoute } from "../../generated/apiRoutes";
2
+ import { API_ROUTES, API_VERSION } from "../../generated/apiRoutes";
3
+ import { AutumnApiError } from "../../generated/client";
4
+ import { autumnFetch } from "../../http/autumnFetch";
5
+
6
+ export type ApiCallOptions = {
7
+ route: ApiRoute;
8
+ baseUrl: string;
9
+ secretKey: string;
10
+ /** `--body`: a JSON document, or `-` for stdin. */
11
+ body?: string;
12
+ /** `key=value` arguments, keyed by wire name; a JSON-typed field arrives as text. */
13
+ fields?: Record<string, string>;
14
+ /** `-H "name: value"`, repeatable; a stated header wins over the default. */
15
+ headers?: string[];
16
+ readStdin?: () => Promise<string>;
17
+ fetch?: typeof globalThis.fetch;
18
+ };
19
+
20
+ export const findApiRoute = ({
21
+ group,
22
+ method,
23
+ }: {
24
+ group: string;
25
+ method: string;
26
+ }): ApiRoute | undefined =>
27
+ API_ROUTES.find((route) => route.group === group && route.method === method);
28
+
29
+ export const apiGroups = (): string[] => [
30
+ ...new Set(API_ROUTES.map((route) => route.group)),
31
+ ];
32
+
33
+ /**
34
+ * `customer_id=cus_1`: fields ride as positional pairs rather than flags, so a
35
+ * field named `version` or `config` can never collide with the CLI's own.
36
+ */
37
+ export const parseFieldArgs = ({
38
+ args,
39
+ }: {
40
+ args: string[];
41
+ }): Record<string, string> => {
42
+ const fields: Record<string, string> = {};
43
+ for (const arg of args) {
44
+ const at = arg.indexOf("=");
45
+ if (at <= 0)
46
+ throw new Error(
47
+ `Expected key=value, got ${JSON.stringify(arg)}. Pass the whole body with --body instead.`,
48
+ );
49
+ fields[arg.slice(0, at)] = arg.slice(at + 1);
50
+ }
51
+ return fields;
52
+ };
53
+
54
+ const parseJson = ({ text, what }: { text: string; what: string }): unknown => {
55
+ try {
56
+ return JSON.parse(text);
57
+ } catch (error) {
58
+ const detail = error instanceof Error ? error.message : String(error);
59
+ throw new Error(`${what} is not valid JSON: ${detail}`);
60
+ }
61
+ };
62
+
63
+ const coerce = ({
64
+ field,
65
+ value,
66
+ }: {
67
+ field: ApiField;
68
+ value: string;
69
+ }): unknown => {
70
+ switch (field.type) {
71
+ case "boolean": {
72
+ if (value === "true") return true;
73
+ if (value === "false") return false;
74
+ throw new Error(`${field.name} takes true or false.`);
75
+ }
76
+ case "number": {
77
+ const parsed = Number(value);
78
+ if (value === "" || !Number.isFinite(parsed))
79
+ throw new Error(`${field.name} takes a number.`);
80
+ return parsed;
81
+ }
82
+ case "string":
83
+ return value;
84
+ case "json":
85
+ return parseJson({ text: value, what: field.name });
86
+ }
87
+ };
88
+
89
+ /**
90
+ * `--body` is the whole document; field flags layer on top of it, so a saved
91
+ * JSON body can still be overridden for one call.
92
+ */
93
+ export const buildApiBody = async ({
94
+ route,
95
+ body,
96
+ fields = {},
97
+ readStdin,
98
+ }: {
99
+ route: ApiRoute;
100
+ body?: string;
101
+ fields?: Record<string, string>;
102
+ readStdin?: () => Promise<string>;
103
+ }): Promise<unknown> => {
104
+ const stated = Object.entries(fields);
105
+ let document: unknown = route.body === "array" ? undefined : {};
106
+ if (body !== undefined) {
107
+ const text = body === "-" ? await (readStdin ?? defaultReadStdin)() : body;
108
+ document = parseJson({ text, what: "--body" });
109
+ }
110
+ if (stated.length === 0) return document;
111
+ if (route.body === "array")
112
+ throw new Error(
113
+ `${route.path} takes an array body: pass it with --body, not key=value.`,
114
+ );
115
+ if (
116
+ typeof document !== "object" ||
117
+ document === null ||
118
+ Array.isArray(document)
119
+ )
120
+ throw new Error(
121
+ "--body must be a JSON object when key=value pairs are given.",
122
+ );
123
+ const byName = new Map(route.fields.map((field) => [field.name, field]));
124
+ const merged: Record<string, unknown> = { ...document };
125
+ for (const [name, value] of stated) {
126
+ const field = byName.get(name);
127
+ if (field === undefined)
128
+ throw new Error(
129
+ `${route.path} has no field ${name}. Fields: ${route.fields.map((known) => known.name).join(", ")}.`,
130
+ );
131
+ merged[name] = coerce({ field, value });
132
+ }
133
+ return merged;
134
+ };
135
+
136
+ const defaultReadStdin = async (): Promise<string> => {
137
+ const chunks: Buffer[] = [];
138
+ for await (const chunk of process.stdin) chunks.push(chunk as Buffer);
139
+ return Buffer.concat(chunks).toString("utf8");
140
+ };
141
+
142
+ /** `-H "x-api-version: 2.3.0"` → `["x-api-version", "2.3.0"]`; the name is lowercased like fetch does. */
143
+ export const parseHeaderArgs = ({
144
+ headers,
145
+ }: {
146
+ headers: string[];
147
+ }): Record<string, string> => {
148
+ const parsed: Record<string, string> = {};
149
+ for (const header of headers) {
150
+ const at = header.indexOf(":");
151
+ const name = at > 0 ? header.slice(0, at).trim().toLowerCase() : "";
152
+ if (name === "")
153
+ throw new Error(
154
+ `Expected -H "name: value", got ${JSON.stringify(header)}.`,
155
+ );
156
+ parsed[name] = header.slice(at + 1).trim();
157
+ }
158
+ return parsed;
159
+ };
160
+
161
+ export type ApiRequest = {
162
+ url: string;
163
+ headers: Record<string, string>;
164
+ body: string;
165
+ };
166
+
167
+ export const buildApiRequest = async ({
168
+ route,
169
+ baseUrl,
170
+ secretKey,
171
+ body,
172
+ fields,
173
+ headers = [],
174
+ readStdin,
175
+ }: Omit<ApiCallOptions, "fetch">): Promise<ApiRequest> => ({
176
+ url: `${baseUrl}${route.path}`,
177
+ headers: {
178
+ authorization: `Bearer ${secretKey}`,
179
+ "content-type": "application/json",
180
+ "x-api-version": API_VERSION,
181
+ ...parseHeaderArgs({ headers }),
182
+ },
183
+ body: JSON.stringify(
184
+ (await buildApiBody({ route, body, fields, readStdin })) ?? {},
185
+ ),
186
+ });
187
+
188
+ const shellQuote = (text: string): string => `'${text.replace(/'/g, "'\\''")}'`;
189
+
190
+ /** The same request as a curl line, for pasting into a doc or a support
191
+ * thread. The key is shown as the literal name of its env var, on purpose:
192
+ * nothing in the output is a secret, and the reader fills it in. */
193
+ export const renderCurl = ({
194
+ request,
195
+ secretKey,
196
+ secretKeyName,
197
+ }: {
198
+ request: ApiRequest;
199
+ secretKey: string;
200
+ /** The env var the key came from, printed in the key's place. */
201
+ secretKeyName: string;
202
+ }): string =>
203
+ [
204
+ `curl -X POST ${shellQuote(request.url)}`,
205
+ ...Object.entries(request.headers).map(([name, value]) => {
206
+ // An authorization the caller overrode with -H is theirs to show.
207
+ const shown =
208
+ name === "authorization" && value === `Bearer ${secretKey}`
209
+ ? `Bearer $${secretKeyName}`
210
+ : value;
211
+ return ` -H ${shellQuote(`${name}: ${shown}`)}`;
212
+ }),
213
+ ` -d ${shellQuote(request.body)}`,
214
+ ].join(" \\\n");
215
+
216
+ const tryParseJson = ({ text }: { text: string }): unknown => {
217
+ try {
218
+ return JSON.parse(text);
219
+ } catch {
220
+ return text;
221
+ }
222
+ };
223
+
224
+ /** A non-2xx reply, whole: the command prints it rather than a one-line summary. */
225
+ export class ApiResponseError extends AutumnApiError {
226
+ readonly statusText: string;
227
+
228
+ constructor({
229
+ status,
230
+ statusText,
231
+ body,
232
+ path,
233
+ }: {
234
+ status: number;
235
+ statusText: string;
236
+ body: unknown;
237
+ path: string;
238
+ }) {
239
+ super({ status, body, path });
240
+ this.name = "ApiResponseError";
241
+ this.statusText = statusText;
242
+ }
243
+ }
244
+
245
+ /** `HTTP 404 Not Found`, and the body as the server sent it, pretty-printed when it is JSON. */
246
+ export const renderApiResponseError = ({
247
+ error,
248
+ }: {
249
+ error: ApiResponseError;
250
+ }): { statusLine: string; body: string } => ({
251
+ statusLine: `HTTP ${error.status} ${error.statusText}`,
252
+ body:
253
+ typeof error.body === "string"
254
+ ? error.body
255
+ : JSON.stringify(error.body, null, 2),
256
+ });
257
+
258
+ /** One POST, the way the generated client does it, plus the version header the spec pins. */
259
+ export const callApi = async ({
260
+ fetch = autumnFetch,
261
+ ...options
262
+ }: ApiCallOptions): Promise<unknown> => {
263
+ const request = await buildApiRequest(options);
264
+ const response = await fetch(request.url, {
265
+ method: "POST",
266
+ headers: request.headers,
267
+ body: request.body,
268
+ });
269
+ const text = await response.text();
270
+ // A proxy's HTML error page is not JSON; the status and route still matter.
271
+ const parsed: unknown = text ? tryParseJson({ text }) : null;
272
+ if (!response.ok)
273
+ throw new ApiResponseError({
274
+ status: response.status,
275
+ statusText: response.statusText,
276
+ body: parsed,
277
+ path: options.route.path,
278
+ });
279
+ return parsed;
280
+ };
@@ -0,0 +1,121 @@
1
+ import type { Command } from "commander";
2
+ import {
3
+ requireSecretKey,
4
+ type Target,
5
+ targetBaseUrl,
6
+ } from "../../env/resolveTarget";
7
+ import { API_ROUTES, type ApiRoute } from "../../generated/apiRoutes";
8
+ import {
9
+ ApiResponseError,
10
+ buildApiRequest,
11
+ callApi,
12
+ parseFieldArgs,
13
+ renderApiResponseError,
14
+ renderCurl,
15
+ } from "./callApi";
16
+
17
+ const SUMMARY_MAX = 80;
18
+
19
+ /** The first sentence, clipped: the group listing is a table, the method's own --help carries the rest. */
20
+ export const summarize = ({ text }: { text: string }): string => {
21
+ const sentence = /^.*?[.!?](?=\s|$)/.exec(text)?.[0] ?? text;
22
+ return sentence.length <= SUMMARY_MAX
23
+ ? sentence
24
+ : `${sentence.slice(0, SUMMARY_MAX - 1).trimEnd()}…`;
25
+ };
26
+
27
+ const fieldHelp = ({ route }: { route: ApiRoute }): string => {
28
+ if (route.body === "none") return "\nTakes no body.";
29
+ if (route.body === "array")
30
+ return "\nTakes a JSON array: pass it with --body '[...]' or --body - (stdin).";
31
+ const width = Math.max(0, ...route.fields.map((field) => field.name.length));
32
+ return [
33
+ "\nFields (key=value; json values are parsed):",
34
+ ...route.fields.map((field) => {
35
+ const type = `${field.type}${field.required ? ", required" : ""}`;
36
+ return ` ${field.name.padEnd(width)} ${type.padEnd(18)}${field.description ?? ""}`.trimEnd();
37
+ }),
38
+ ].join("\n");
39
+ };
40
+
41
+ /**
42
+ * One subcommand per public RPC route, straight off the spec: `atmn api
43
+ * balances check customer_id=cus_1 feature_id=messages`. Nothing here knows
44
+ * what any route does; the spec's own description is the help.
45
+ */
46
+ export const registerApiCommands = ({
47
+ program,
48
+ targetOf,
49
+ }: {
50
+ program: Command;
51
+ targetOf: (command: Command) => Target;
52
+ }): void => {
53
+ const api = program
54
+ .command("api")
55
+ .description(
56
+ "call any public API route: atmn api <group> <method> [key=value...]",
57
+ );
58
+ const groups = new Map<string, Command>();
59
+ for (const route of API_ROUTES) {
60
+ let group = groups.get(route.group);
61
+ if (group === undefined) {
62
+ group = api.command(route.group).description(`${route.group}.* routes`);
63
+ groups.set(route.group, group);
64
+ }
65
+ group
66
+ .command(route.method)
67
+ .summary(summarize({ text: route.description ?? route.path }))
68
+ .description(route.description ?? route.path)
69
+ .argument("[fields...]", "body fields as key=value")
70
+ .option("--body <json>", "the whole JSON body; - reads stdin")
71
+ .option(
72
+ "-H, --header <header>",
73
+ 'an extra request header, "name: value"; repeatable',
74
+ (value: string, previous: string[] = []) => [...previous, value],
75
+ )
76
+ .option(
77
+ "--curl",
78
+ "print the request as a curl command instead of sending it",
79
+ )
80
+ .addHelpText("after", fieldHelp({ route }))
81
+ .action(
82
+ async (
83
+ args: string[],
84
+ options: { body?: string; header?: string[]; curl?: boolean },
85
+ command: Command,
86
+ ) => {
87
+ const target = targetOf(command);
88
+ const call = {
89
+ route,
90
+ baseUrl: targetBaseUrl({ target }),
91
+ secretKey: requireSecretKey({ target }),
92
+ ...(options.body === undefined ? {} : { body: options.body }),
93
+ fields: parseFieldArgs({ args }),
94
+ headers: options.header ?? [],
95
+ };
96
+ if (options.curl === true) {
97
+ process.stdout.write(
98
+ `${renderCurl({
99
+ request: await buildApiRequest(call),
100
+ secretKey: call.secretKey,
101
+ secretKeyName: target.secretKeyName,
102
+ })}\n`,
103
+ );
104
+ return;
105
+ }
106
+ try {
107
+ const response = await callApi(call);
108
+ process.stdout.write(`${JSON.stringify(response, null, 2)}\n`);
109
+ } catch (error) {
110
+ // The server's reply is the answer, so it is shown whole: the
111
+ // status line on stderr, the body on stdout like a success.
112
+ if (!(error instanceof ApiResponseError)) throw error;
113
+ const { statusLine, body } = renderApiResponseError({ error });
114
+ process.stderr.write(`${statusLine}\n`);
115
+ process.stdout.write(`${body}\n`);
116
+ process.exitCode = 1;
117
+ }
118
+ },
119
+ );
120
+ }
121
+ };
@@ -0,0 +1,32 @@
1
+ import { AutumnApiError } from "../../generated/client";
2
+ import { autumnFetch } from "../../http/autumnFetch";
3
+ import type { OrgInfo } from "./types/orgInfo";
4
+
5
+ const ORG_INFO_PATH = "/v1/organization/me";
6
+
7
+ /** Not in the spec, so hand-written like the key-minting call rather than generated. */
8
+ export const fetchOrgInfo = async ({
9
+ baseUrl,
10
+ secretKey,
11
+ fetch = autumnFetch,
12
+ }: {
13
+ baseUrl: string;
14
+ secretKey: string;
15
+ fetch?: typeof globalThis.fetch;
16
+ }): Promise<OrgInfo> => {
17
+ const response = await fetch(`${baseUrl}${ORG_INFO_PATH}`, {
18
+ method: "GET",
19
+ headers: { authorization: `Bearer ${secretKey}` },
20
+ });
21
+
22
+ const text = await response.text();
23
+ const body: unknown = text ? JSON.parse(text) : null;
24
+ if (!response.ok) {
25
+ throw new AutumnApiError({
26
+ status: response.status,
27
+ body,
28
+ path: ORG_INFO_PATH,
29
+ });
30
+ }
31
+ return body as OrgInfo;
32
+ };
@@ -0,0 +1,18 @@
1
+ /** What the server says about the key it was given: the org and the env it unlocks. */
2
+ export type OrgInfo = {
3
+ id: string;
4
+ name: string;
5
+ slug: string;
6
+ env: string;
7
+ /** True when the key belongs to a sandbox sub-org rather than the main one. */
8
+ is_sandbox?: boolean;
9
+ /** The main organization's id, for a sandbox. */
10
+ created_by?: string | null;
11
+ /** `pending` while a keyless org has no owner; null for an ordinary org. */
12
+ claim_state?: "pending" | "claimed" | "expiring" | null;
13
+ /** When a pending claim window closes, ISO 8601. */
14
+ claim_expires_at?: string | null;
15
+ user?: { id: string; email: string; name: string };
16
+ };
17
+
18
+ export type FetchOrgInfo = () => Promise<OrgInfo>;