auramaxx 0.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.
- package/LICENSE +26 -0
- package/README.md +77 -0
- package/apps/desktop-electron/main.js +428 -0
- package/bin/auramaxx.js +1063 -0
- package/docs/ADAPTERS.md +466 -0
- package/docs/AGENT_SETUP.md +159 -0
- package/docs/API.md +127 -0
- package/docs/APPS.md +199 -0
- package/docs/ARCHITECTURE.md +235 -0
- package/docs/AUTH.md +318 -0
- package/docs/BEST-PRACTICES.md +82 -0
- package/docs/CLI.md +141 -0
- package/docs/DESKTOP_ELECTRON.md +26 -0
- package/docs/DEVELOPING-APPS.md +453 -0
- package/docs/MCP.md +122 -0
- package/docs/PACKAGING_POLICY.md +19 -0
- package/docs/PERMISSION.md +137 -0
- package/docs/PROTOCOL.md +142 -0
- package/docs/README.md +50 -0
- package/docs/SKILLS.md +132 -0
- package/docs/TROUBLESHOOTING.md +376 -0
- package/docs/WORKSPACE.md +673 -0
- package/docs/agent-auth.md +14 -0
- package/docs/api/authentication.md +79 -0
- package/docs/api/secrets/api-keys.md +28 -0
- package/docs/api/secrets/credentials.md +80 -0
- package/docs/api/secrets/sharing.md +48 -0
- package/docs/api/system.md +41 -0
- package/docs/api/wallets/apps-strategies.md +66 -0
- package/docs/api/wallets/core.md +46 -0
- package/docs/api/wallets/data-portfolio.md +42 -0
- package/docs/aura-file.md +48 -0
- package/docs/core-concepts/FEATURES.md +114 -0
- package/docs/credentials.md +120 -0
- package/docs/external/HOW_TO_AURAMAXX/GETTING_SECRETS.md +33 -0
- package/docs/external/HOW_TO_AURAMAXX/README.md +45 -0
- package/docs/external/getting-started.md +10 -0
- package/docs/external/overview.md +19 -0
- package/docs/external/persona-paths.md +7 -0
- package/docs/external/share-secret.md +76 -0
- package/docs/external/why-aura.md +7 -0
- package/docs/security.md +227 -0
- package/docs/templates/RELEASE_NOTES_TEMPLATE.md +22 -0
- package/docs/wallet/AI.md +508 -0
- package/docs/wallet/DEVELOPING-STRATEGIES.md +713 -0
- package/docs/wallet/README.md +47 -0
- package/docs/wallet/STRATEGY.md +89 -0
- package/next.config.ts +28 -0
- package/package.json +167 -0
- package/postcss.config.mjs +8 -0
- package/prisma/migrations/20260214170000_baseline/migration.sql +511 -0
- package/prisma/migrations/20260216214537_add_passkey_model/migration.sql +18 -0
- package/prisma/migrations/20260217150500_add_credential_access_audit/migration.sql +31 -0
- package/prisma/migrations/20260222090000_update_admin_ttl_default/migration.sql +10 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +447 -0
- package/public/logo.webp +0 -0
- package/scripts/add-app.js +245 -0
- package/server/abi/SwapHelper.json +438 -0
- package/server/cli/approval.ts +447 -0
- package/server/cli/commands/actions.ts +474 -0
- package/server/cli/commands/api.ts +220 -0
- package/server/cli/commands/apikey.ts +277 -0
- package/server/cli/commands/app.ts +204 -0
- package/server/cli/commands/auth.ts +464 -0
- package/server/cli/commands/cron.ts +24 -0
- package/server/cli/commands/diary.ts +274 -0
- package/server/cli/commands/doctor.ts +1247 -0
- package/server/cli/commands/env.ts +476 -0
- package/server/cli/commands/experimental.ts +69 -0
- package/server/cli/commands/init.ts +798 -0
- package/server/cli/commands/lock.ts +157 -0
- package/server/cli/commands/mcp.ts +285 -0
- package/server/cli/commands/quickhack.ts +86 -0
- package/server/cli/commands/release-check.ts +231 -0
- package/server/cli/commands/restore.ts +314 -0
- package/server/cli/commands/service.ts +320 -0
- package/server/cli/commands/shell-hook.ts +512 -0
- package/server/cli/commands/skill.ts +216 -0
- package/server/cli/commands/start.ts +139 -0
- package/server/cli/commands/status.ts +59 -0
- package/server/cli/commands/stop.ts +36 -0
- package/server/cli/commands/token.ts +180 -0
- package/server/cli/commands/unlock.ts +50 -0
- package/server/cli/commands/vault.ts +1323 -0
- package/server/cli/commands/wallet.ts +209 -0
- package/server/cli/index.ts +280 -0
- package/server/cli/lib/approval-poll.ts +94 -0
- package/server/cli/lib/aura-parser.ts +64 -0
- package/server/cli/lib/credential-create.ts +74 -0
- package/server/cli/lib/credential-resolve.ts +280 -0
- package/server/cli/lib/dotenv-migrate.ts +116 -0
- package/server/cli/lib/dotenv-parser.ts +146 -0
- package/server/cli/lib/escalation.ts +57 -0
- package/server/cli/lib/http.ts +91 -0
- package/server/cli/lib/init-steps.ts +76 -0
- package/server/cli/lib/local-agent-trust.ts +45 -0
- package/server/cli/lib/lock-unlock-helper.ts +71 -0
- package/server/cli/lib/process.ts +162 -0
- package/server/cli/lib/prompt.ts +294 -0
- package/server/cli/lib/theme.ts +240 -0
- package/server/cli/socket.ts +579 -0
- package/server/cli/transport-client.ts +50 -0
- package/server/cron/index.ts +137 -0
- package/server/cron/job.ts +31 -0
- package/server/cron/jobs/balance-sync.ts +436 -0
- package/server/cron/jobs/incoming-scan.ts +506 -0
- package/server/cron/jobs/native-price.ts +70 -0
- package/server/cron/jobs/orphan-cleanup.ts +40 -0
- package/server/cron/jobs/strategy-runner.ts +175 -0
- package/server/cron/scheduler.ts +125 -0
- package/server/index.ts +420 -0
- package/server/lib/adapters/factory.ts +119 -0
- package/server/lib/adapters/index.ts +19 -0
- package/server/lib/adapters/router.ts +297 -0
- package/server/lib/adapters/telegram.ts +645 -0
- package/server/lib/adapters/types.ts +89 -0
- package/server/lib/adapters/webhook.ts +95 -0
- package/server/lib/address.ts +49 -0
- package/server/lib/agent-auth/contracts.ts +1194 -0
- package/server/lib/agent-profiles.ts +419 -0
- package/server/lib/ai.ts +285 -0
- package/server/lib/api-registry/contracts.ts +86 -0
- package/server/lib/api-registry/validation.ts +172 -0
- package/server/lib/apikey-migration.ts +258 -0
- package/server/lib/app-installer.ts +505 -0
- package/server/lib/app-tokens.ts +247 -0
- package/server/lib/approval-link.ts +27 -0
- package/server/lib/auth.ts +314 -0
- package/server/lib/auto-execute.ts +160 -0
- package/server/lib/batch.ts +242 -0
- package/server/lib/cold.ts +1048 -0
- package/server/lib/config.ts +408 -0
- package/server/lib/credential-access-audit.ts +85 -0
- package/server/lib/credential-access-policy.ts +111 -0
- package/server/lib/credential-health.ts +343 -0
- package/server/lib/credential-import.ts +608 -0
- package/server/lib/credential-scope.ts +102 -0
- package/server/lib/credential-shares.ts +190 -0
- package/server/lib/credential-transport.ts +533 -0
- package/server/lib/credential-vault.ts +77 -0
- package/server/lib/credentials.ts +422 -0
- package/server/lib/crypto.ts +8 -0
- package/server/lib/db.ts +58 -0
- package/server/lib/defaults.ts +386 -0
- package/server/lib/dex/index.ts +80 -0
- package/server/lib/dex/relay.ts +235 -0
- package/server/lib/dex/types.ts +59 -0
- package/server/lib/dex/uniswap.ts +370 -0
- package/server/lib/diary.ts +34 -0
- package/server/lib/dont-ask-again-policy.ts +41 -0
- package/server/lib/e2e-agent/artifacts.ts +36 -0
- package/server/lib/e2e-agent/contracts.ts +112 -0
- package/server/lib/e2e-agent/validation.ts +135 -0
- package/server/lib/encrypt.ts +114 -0
- package/server/lib/error.ts +20 -0
- package/server/lib/events.ts +217 -0
- package/server/lib/feature-flags.ts +93 -0
- package/server/lib/hot.ts +357 -0
- package/server/lib/human-action-summary.ts +80 -0
- package/server/lib/key-fingerprint.ts +28 -0
- package/server/lib/logger.ts +340 -0
- package/server/lib/network.ts +137 -0
- package/server/lib/notifications.ts +230 -0
- package/server/lib/oauth2-refresh.ts +241 -0
- package/server/lib/oursecret.ts +71 -0
- package/server/lib/passkey-credential.ts +360 -0
- package/server/lib/passkey.ts +68 -0
- package/server/lib/permissions.ts +299 -0
- package/server/lib/pino.ts +24 -0
- package/server/lib/policy-preview.ts +138 -0
- package/server/lib/price.ts +338 -0
- package/server/lib/prices.ts +34 -0
- package/server/lib/project-scope.ts +297 -0
- package/server/lib/resolve-action.ts +328 -0
- package/server/lib/resolve.ts +36 -0
- package/server/lib/secret-gist-share.ts +296 -0
- package/server/lib/sessions.ts +634 -0
- package/server/lib/socket-path.ts +56 -0
- package/server/lib/solana/connection.ts +26 -0
- package/server/lib/solana/jupiter.ts +128 -0
- package/server/lib/solana/transfer.ts +108 -0
- package/server/lib/solana/wallet.ts +136 -0
- package/server/lib/strategy/emits.ts +21 -0
- package/server/lib/strategy/engine.ts +1305 -0
- package/server/lib/strategy/executor.ts +115 -0
- package/server/lib/strategy/hook-context.ts +159 -0
- package/server/lib/strategy/hooks.ts +990 -0
- package/server/lib/strategy/index.ts +28 -0
- package/server/lib/strategy/installer.ts +305 -0
- package/server/lib/strategy/loader.ts +256 -0
- package/server/lib/strategy/message.ts +237 -0
- package/server/lib/strategy/repository.ts +218 -0
- package/server/lib/strategy/session-logger.ts +693 -0
- package/server/lib/strategy/sources.ts +288 -0
- package/server/lib/strategy/state.ts +189 -0
- package/server/lib/strategy/templates.ts +403 -0
- package/server/lib/strategy/tick.ts +404 -0
- package/server/lib/strategy/types.ts +230 -0
- package/server/lib/swap.ts +3 -0
- package/server/lib/temp.ts +86 -0
- package/server/lib/token-metadata.ts +86 -0
- package/server/lib/token-safety.ts +200 -0
- package/server/lib/token-search.ts +444 -0
- package/server/lib/totp.ts +194 -0
- package/server/lib/transactions.ts +123 -0
- package/server/lib/transport.ts +84 -0
- package/server/lib/txhistory/decoder.ts +262 -0
- package/server/lib/txhistory/enricher.ts +652 -0
- package/server/lib/txhistory/index.ts +391 -0
- package/server/lib/txhistory/signatures.ts +59 -0
- package/server/lib/update-check.ts +35 -0
- package/server/lib/verified-summary.ts +414 -0
- package/server/lib/view-registry.ts +80 -0
- package/server/mcp/profile-policy.ts +30 -0
- package/server/mcp/server.ts +1589 -0
- package/server/mcp/tools.ts +276 -0
- package/server/middleware/auth.ts +119 -0
- package/server/middleware/requestLogger.ts +84 -0
- package/server/routes/actions.ts +539 -0
- package/server/routes/adapters.ts +711 -0
- package/server/routes/addressbook.ts +113 -0
- package/server/routes/ai.ts +34 -0
- package/server/routes/apikeys.ts +343 -0
- package/server/routes/apps.ts +601 -0
- package/server/routes/auth.ts +406 -0
- package/server/routes/backup.ts +404 -0
- package/server/routes/batch.ts +270 -0
- package/server/routes/bookmarks.ts +162 -0
- package/server/routes/credential-shares.ts +380 -0
- package/server/routes/credential-vaults.ts +159 -0
- package/server/routes/credentials.ts +1782 -0
- package/server/routes/dashboard.ts +97 -0
- package/server/routes/defaults.ts +124 -0
- package/server/routes/flags.ts +11 -0
- package/server/routes/fund.ts +225 -0
- package/server/routes/heartbeat.ts +375 -0
- package/server/routes/import.ts +364 -0
- package/server/routes/launch.ts +665 -0
- package/server/routes/lock.ts +54 -0
- package/server/routes/logs.ts +68 -0
- package/server/routes/nuke.ts +111 -0
- package/server/routes/passkey-credentials.ts +99 -0
- package/server/routes/passkey.ts +366 -0
- package/server/routes/portfolio.ts +217 -0
- package/server/routes/price.ts +63 -0
- package/server/routes/resolve.ts +31 -0
- package/server/routes/security.ts +45 -0
- package/server/routes/send-evm.ts +241 -0
- package/server/routes/send-solana.ts +281 -0
- package/server/routes/send.ts +178 -0
- package/server/routes/setup.ts +210 -0
- package/server/routes/strategy.ts +894 -0
- package/server/routes/swap-evm.ts +352 -0
- package/server/routes/swap-solana.ts +176 -0
- package/server/routes/swap.ts +356 -0
- package/server/routes/token.ts +247 -0
- package/server/routes/unlock.ts +467 -0
- package/server/routes/views.ts +41 -0
- package/server/routes/wallet-assets.ts +361 -0
- package/server/routes/wallet-transactions.ts +515 -0
- package/server/routes/wallet.ts +709 -0
- package/server/types.ts +146 -0
- package/shared/credential-field-schema.ts +248 -0
- package/skills/auramaxx/HEARTBEAT.md +78 -0
- package/skills/auramaxx/SKILL.md +745 -0
- package/skills/auramaxx/docs/AGENT_SETUP.md +155 -0
- package/skills/auramaxx/docs/API.md +127 -0
- package/skills/auramaxx/docs/AUTH.md +318 -0
- package/skills/auramaxx/docs/CLI.md +130 -0
- package/skills/auramaxx/docs/MCP.md +122 -0
- package/skills/auramaxx/docs/TROUBLESHOOTING.md +357 -0
- package/skills/auramaxx/docs/WORKSPACE.md +673 -0
- package/skills/auramaxx/docs/security.md +227 -0
- package/skills/task-lifecycle/SKILL.md +378 -0
- package/src/app/api/[...doc]/page.tsx +36 -0
- package/src/app/api/agent-requests/route.ts +30 -0
- package/src/app/api/apps/install/route.ts +132 -0
- package/src/app/api/apps/manifests/route.ts +16 -0
- package/src/app/api/apps/static/[...path]/route.ts +57 -0
- package/src/app/api/docs/plain/route.ts +74 -0
- package/src/app/api/events/route.ts +92 -0
- package/src/app/api/page.tsx +290 -0
- package/src/app/api/workspace/[id]/apps/[wid]/route.ts +119 -0
- package/src/app/api/workspace/[id]/apps/route.ts +81 -0
- package/src/app/api/workspace/[id]/export/route.ts +67 -0
- package/src/app/api/workspace/[id]/route.ts +168 -0
- package/src/app/api/workspace/auth.ts +40 -0
- package/src/app/api/workspace/config/route.ts +121 -0
- package/src/app/api/workspace/import/route.ts +127 -0
- package/src/app/api/workspace/route.ts +116 -0
- package/src/app/app-legacy-do-not-use/page.tsx +2245 -0
- package/src/app/apple-icon.png +0 -0
- package/src/app/approve/[actionId]/page.tsx +409 -0
- package/src/app/docs/DocsPageContent.tsx +269 -0
- package/src/app/docs/[...doc]/page.tsx +41 -0
- package/src/app/docs/page.tsx +38 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +819 -0
- package/src/app/health/page.tsx +5 -0
- package/src/app/hello/page.tsx +102 -0
- package/src/app/icon.png +0 -0
- package/src/app/layout.tsx +39 -0
- package/src/app/page.tsx +1964 -0
- package/src/app/privacy/page.tsx +63 -0
- package/src/app/providers.tsx +87 -0
- package/src/app/share/[token]/page.tsx +295 -0
- package/src/app/terms/page.tsx +80 -0
- package/src/components/ChainSelector.tsx +44 -0
- package/src/components/HumanActionBar.tsx +697 -0
- package/src/components/NotificationDrawer.tsx +387 -0
- package/src/components/PasskeyEnrollmentPrompt.tsx +235 -0
- package/src/components/apps/AgentKeysApp.tsx +490 -0
- package/src/components/apps/App.tsx +153 -0
- package/src/components/apps/AppGrid.tsx +15 -0
- package/src/components/apps/DetailedAddressDrawer.tsx +325 -0
- package/src/components/apps/DraggableApp.tsx +562 -0
- package/src/components/apps/IFrameApp.tsx +73 -0
- package/src/components/apps/LogsApp.tsx +360 -0
- package/src/components/apps/SendApp.tsx +394 -0
- package/src/components/apps/SetupWizardApp.tsx +1004 -0
- package/src/components/apps/SystemDefaultsApp.tsx +845 -0
- package/src/components/apps/ThirdPartyApp.tsx +428 -0
- package/src/components/apps/TokenApp.tsx +319 -0
- package/src/components/apps/TransactionsApp.tsx +438 -0
- package/src/components/apps/WalletDetailApp.tsx +1505 -0
- package/src/components/apps/index.ts +13 -0
- package/src/components/design-system/Button.tsx +88 -0
- package/src/components/design-system/ChainIndicator.tsx +65 -0
- package/src/components/design-system/ChainSelector.tsx +147 -0
- package/src/components/design-system/ConfirmationModal.tsx +107 -0
- package/src/components/design-system/ConfirmationPopover.tsx +81 -0
- package/src/components/design-system/DownloadButton.tsx +149 -0
- package/src/components/design-system/Drawer.tsx +133 -0
- package/src/components/design-system/FilterDropdown.tsx +183 -0
- package/src/components/design-system/ItemPicker.tsx +157 -0
- package/src/components/design-system/Modal.tsx +296 -0
- package/src/components/design-system/Popover.tsx +142 -0
- package/src/components/design-system/TextInput.tsx +85 -0
- package/src/components/design-system/Toggle.tsx +65 -0
- package/src/components/design-system/TyvekCollapsibleSection.tsx +55 -0
- package/src/components/design-system/index.ts +14 -0
- package/src/components/docs/ClientSideMarkdown.tsx +51 -0
- package/src/components/docs/DocsSearchBar.tsx +118 -0
- package/src/components/docs/DocsThemeToggle.tsx +38 -0
- package/src/components/docs/PersistentDocGroup.tsx +91 -0
- package/src/components/docs/ShareUrlButton.tsx +33 -0
- package/src/components/docs/SidebarScrollMemory.tsx +56 -0
- package/src/components/health/CredentialHealthDashboard.tsx +214 -0
- package/src/components/icons/ChainIcons.tsx +72 -0
- package/src/components/layout/AppStoreDrawer.tsx +369 -0
- package/src/components/layout/ContentArea.tsx +21 -0
- package/src/components/layout/CreateViewModal.tsx +88 -0
- package/src/components/layout/LeftRail.tsx +114 -0
- package/src/components/layout/TabBar.tsx +284 -0
- package/src/components/layout/WalletSidebar.tsx +1030 -0
- package/src/components/layout/index.ts +6 -0
- package/src/components/marketing/AuraMaxxSpecOverlay.tsx +653 -0
- package/src/components/marketing/DeviceMorphExperience.tsx +216 -0
- package/src/components/vault/ApiKeysConsole.tsx +1272 -0
- package/src/components/vault/AuditConsole.tsx +600 -0
- package/src/components/vault/CredentialDetail.tsx +625 -0
- package/src/components/vault/CredentialEmpty.tsx +55 -0
- package/src/components/vault/CredentialField.tsx +583 -0
- package/src/components/vault/CredentialForm.tsx +1484 -0
- package/src/components/vault/CredentialList.tsx +265 -0
- package/src/components/vault/CredentialRow.tsx +130 -0
- package/src/components/vault/CredentialShareModal.tsx +273 -0
- package/src/components/vault/CredentialVault.tsx +1662 -0
- package/src/components/vault/CredentialWalletWidget.tsx +103 -0
- package/src/components/vault/DocsConsole.tsx +113 -0
- package/src/components/vault/ImportCredentialsModal.tsx +578 -0
- package/src/components/vault/LargeTypeModal.tsx +88 -0
- package/src/components/vault/PasswordGenerator.tsx +232 -0
- package/src/components/vault/TOTPDisplay.tsx +108 -0
- package/src/components/vault/TotpSetupPanel.tsx +198 -0
- package/src/components/vault/VaultSidebar.tsx +881 -0
- package/src/components/vault/credentialFormName.ts +91 -0
- package/src/components/vault/hooks/useVaultKeyboardShortcuts.ts +69 -0
- package/src/components/vault/types.ts +56 -0
- package/src/context/AuthContext.tsx +365 -0
- package/src/context/PriceContext.tsx +113 -0
- package/src/context/ThemeContext.tsx +164 -0
- package/src/context/WebSocketContext.tsx +269 -0
- package/src/context/WorkspaceContext.tsx +668 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useAgentActions.ts +552 -0
- package/src/hooks/useBalance.ts +103 -0
- package/src/hooks/useBalances.ts +129 -0
- package/src/hooks/useTheme.ts +156 -0
- package/src/instrumentation.ts +12 -0
- package/src/lib/api-docs.ts +154 -0
- package/src/lib/api.ts +474 -0
- package/src/lib/app-loader.ts +148 -0
- package/src/lib/app-registry.ts +178 -0
- package/src/lib/app-sdk.ts +157 -0
- package/src/lib/audit-console-adapter.ts +151 -0
- package/src/lib/auth-client.ts +75 -0
- package/src/lib/config.ts +74 -0
- package/src/lib/credential-field-schema.ts +11 -0
- package/src/lib/crypto.ts +112 -0
- package/src/lib/db.ts +21 -0
- package/src/lib/docs.ts +544 -0
- package/src/lib/events.ts +363 -0
- package/src/lib/pino.ts +24 -0
- package/src/lib/theme-handlers.ts +168 -0
- package/src/lib/theme.ts +351 -0
- package/src/lib/tokenData.ts +378 -0
- package/src/lib/totp-import.ts +57 -0
- package/src/lib/vault-crypto.ts +129 -0
- package/src/lib/view-registry.ts +57 -0
- package/src/lib/websocket-server.ts +302 -0
- package/src/lib/websocket-setup.ts +79 -0
- package/src/lib/wordlist.ts +2050 -0
- package/src/lib/workspace-handlers.ts +285 -0
- package/start.sh +170 -0
- package/tailwind.config.ts +99 -0
- package/tsconfig.json +42 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auramaxx shell-hook — Auto-load .aura env vars on cd (like direnv)
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* aura shell-hook bash Output bash hook script
|
|
6
|
+
* aura shell-hook zsh Output zsh hook script
|
|
7
|
+
* aura shell-hook install Auto-detect shell, add to rc file
|
|
8
|
+
* aura shell-hook allow Whitelist current directory
|
|
9
|
+
* aura shell-hook deny Remove directory from whitelist
|
|
10
|
+
* aura shell-hook status Show whitelist + active dir
|
|
11
|
+
* aura shell-hook resolve Internal: resolve .aura and output export statements
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import * as fs from 'fs';
|
|
15
|
+
import * as path from 'path';
|
|
16
|
+
import * as crypto from 'crypto';
|
|
17
|
+
import * as os from 'os';
|
|
18
|
+
import { getErrorMessage } from '../../lib/error';
|
|
19
|
+
import {
|
|
20
|
+
escapeForShell,
|
|
21
|
+
searchCredential,
|
|
22
|
+
readCredential,
|
|
23
|
+
validateEnvVarName,
|
|
24
|
+
} from '../lib/credential-resolve';
|
|
25
|
+
|
|
26
|
+
// ── Paths ──
|
|
27
|
+
|
|
28
|
+
const AURA_DIR = process.env.WALLET_DATA_DIR || path.join(os.homedir(), '.auramaxx');
|
|
29
|
+
const ALLOWED_FILE = path.join(AURA_DIR, 'shell-allowed.json');
|
|
30
|
+
const CACHE_DIR = path.join(AURA_DIR, 'shell-cache');
|
|
31
|
+
const CACHE_SECRET_FILE = path.join(AURA_DIR, 'shell-cache.secret');
|
|
32
|
+
|
|
33
|
+
// ── Whitelist ──
|
|
34
|
+
|
|
35
|
+
interface AllowedEntry {
|
|
36
|
+
allowedAt: string;
|
|
37
|
+
hash: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function loadAllowed(): Record<string, AllowedEntry> {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(fs.readFileSync(ALLOWED_FILE, 'utf-8'));
|
|
43
|
+
} catch {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function saveAllowed(allowed: Record<string, AllowedEntry>): void {
|
|
49
|
+
fs.mkdirSync(path.dirname(ALLOWED_FILE), { recursive: true, mode: 0o700 });
|
|
50
|
+
const fd = fs.openSync(ALLOWED_FILE, 'w', 0o600);
|
|
51
|
+
fs.writeSync(fd, JSON.stringify(allowed, null, 2) + '\n');
|
|
52
|
+
fs.closeSync(fd);
|
|
53
|
+
fs.chmodSync(ALLOWED_FILE, 0o600);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function hashFile(filePath: string): string {
|
|
57
|
+
const content = fs.readFileSync(filePath);
|
|
58
|
+
return crypto.createHash('sha256').update(content).digest('hex').slice(0, 16);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ── Cache ──
|
|
62
|
+
|
|
63
|
+
function getOrCreateCacheSecret(): string {
|
|
64
|
+
try {
|
|
65
|
+
const existing = fs.readFileSync(CACHE_SECRET_FILE, 'utf-8').trim();
|
|
66
|
+
if (existing) {
|
|
67
|
+
try { fs.chmodSync(CACHE_SECRET_FILE, 0o600); } catch {}
|
|
68
|
+
return existing;
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
// fall through and recreate
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const secret = crypto.randomBytes(32).toString('base64url');
|
|
75
|
+
fs.mkdirSync(path.dirname(CACHE_SECRET_FILE), { recursive: true, mode: 0o700 });
|
|
76
|
+
const fd = fs.openSync(CACHE_SECRET_FILE, 'w', 0o600);
|
|
77
|
+
fs.writeSync(fd, secret);
|
|
78
|
+
fs.closeSync(fd);
|
|
79
|
+
fs.chmodSync(CACHE_SECRET_FILE, 0o600);
|
|
80
|
+
return secret;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface CacheEntry {
|
|
84
|
+
vars: Record<string, string>;
|
|
85
|
+
expiresAt: number;
|
|
86
|
+
auraHash: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
90
|
+
|
|
91
|
+
function getCacheKey(dir: string): string {
|
|
92
|
+
// Key cache filenames with install-local secret material so paths are not
|
|
93
|
+
// deterministically hashable from directory names alone.
|
|
94
|
+
const secret = getOrCreateCacheSecret();
|
|
95
|
+
return crypto.createHmac('sha256', secret).update(dir).digest('hex').slice(0, 16);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function getLegacyCacheKey(dir: string): string {
|
|
99
|
+
return crypto.createHash('sha256').update(dir).digest('hex').slice(0, 16);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getCache(dir: string, auraHash: string): Record<string, string> | null {
|
|
103
|
+
const cacheFile = path.join(CACHE_DIR, `${getCacheKey(dir)}.json`);
|
|
104
|
+
const legacyCacheFile = path.join(CACHE_DIR, `${getLegacyCacheKey(dir)}.json`);
|
|
105
|
+
|
|
106
|
+
// Intentional invalidation of legacy deterministic cache filenames.
|
|
107
|
+
try { fs.unlinkSync(legacyCacheFile); } catch {}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const raw = fs.readFileSync(cacheFile, 'utf-8');
|
|
111
|
+
const trimmed = raw.trimStart();
|
|
112
|
+
// Try encrypted format first, fall back to legacy plaintext
|
|
113
|
+
let entry: CacheEntry;
|
|
114
|
+
if (trimmed.startsWith('{')) {
|
|
115
|
+
// Legacy plaintext — delete it (audit finding #2)
|
|
116
|
+
fs.unlinkSync(cacheFile);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
entry = JSON.parse(decryptCacheEntry(raw));
|
|
120
|
+
if (!entry || typeof entry !== 'object' || typeof entry.expiresAt !== 'number' || typeof entry.auraHash !== 'string' || typeof entry.vars !== 'object' || entry.vars === null) {
|
|
121
|
+
throw new Error('invalid cache entry payload');
|
|
122
|
+
}
|
|
123
|
+
if (entry.expiresAt > Date.now() && entry.auraHash === auraHash) {
|
|
124
|
+
return entry.vars;
|
|
125
|
+
}
|
|
126
|
+
} catch {
|
|
127
|
+
// Cache miss or decryption failure — best-effort cleanup of corrupt entries
|
|
128
|
+
try { fs.unlinkSync(cacheFile); } catch {}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Derive a machine- and install-local encryption key for cache at rest.
|
|
135
|
+
* Includes a per-install secret stored under ~/.auramaxx to avoid
|
|
136
|
+
* deterministic, host/user-only key derivation.
|
|
137
|
+
*/
|
|
138
|
+
function getCacheEncryptionKey(): Buffer {
|
|
139
|
+
const material = `auramaxx-cache:${AURA_DIR}:${getOrCreateCacheSecret()}`;
|
|
140
|
+
return crypto.createHash('sha256').update(material).digest();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function encryptCacheEntry(data: string): string {
|
|
144
|
+
const key = getCacheEncryptionKey();
|
|
145
|
+
const iv = crypto.randomBytes(12);
|
|
146
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
147
|
+
const encrypted = Buffer.concat([cipher.update(data, 'utf-8'), cipher.final()]);
|
|
148
|
+
const tag = cipher.getAuthTag();
|
|
149
|
+
// Format: iv:tag:ciphertext (all base64)
|
|
150
|
+
return `${iv.toString('base64')}:${tag.toString('base64')}:${encrypted.toString('base64')}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function decryptCacheEntry(blob: string): string {
|
|
154
|
+
const key = getCacheEncryptionKey();
|
|
155
|
+
const parts = blob.split(':');
|
|
156
|
+
if (parts.length !== 3) {
|
|
157
|
+
throw new Error('invalid cache entry format');
|
|
158
|
+
}
|
|
159
|
+
const [ivB64, tagB64, ctB64] = parts;
|
|
160
|
+
const iv = Buffer.from(ivB64, 'base64');
|
|
161
|
+
const tag = Buffer.from(tagB64, 'base64');
|
|
162
|
+
const ct = Buffer.from(ctB64, 'base64');
|
|
163
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
|
|
164
|
+
decipher.setAuthTag(tag);
|
|
165
|
+
return Buffer.concat([decipher.update(ct), decipher.final()]).toString('utf-8');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function setCache(dir: string, vars: Record<string, string>, auraHash: string): void {
|
|
169
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true, mode: 0o700 });
|
|
170
|
+
try { fs.chmodSync(CACHE_DIR, 0o700); } catch {}
|
|
171
|
+
const cacheFile = path.join(CACHE_DIR, `${getCacheKey(dir)}.json`);
|
|
172
|
+
const legacyCacheFile = path.join(CACHE_DIR, `${getLegacyCacheKey(dir)}.json`);
|
|
173
|
+
try { fs.unlinkSync(legacyCacheFile); } catch {}
|
|
174
|
+
const entry: CacheEntry = {
|
|
175
|
+
vars,
|
|
176
|
+
expiresAt: Date.now() + CACHE_TTL_MS,
|
|
177
|
+
auraHash,
|
|
178
|
+
};
|
|
179
|
+
const encrypted = encryptCacheEntry(JSON.stringify(entry));
|
|
180
|
+
const fd = fs.openSync(cacheFile, 'w', 0o600);
|
|
181
|
+
fs.writeSync(fd, encrypted);
|
|
182
|
+
fs.closeSync(fd);
|
|
183
|
+
fs.chmodSync(cacheFile, 0o600);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ── Shell hooks ──
|
|
187
|
+
|
|
188
|
+
function bashHook(): string {
|
|
189
|
+
return `# Aura shell hook — auto-load .aura env vars
|
|
190
|
+
_aura_hook() {
|
|
191
|
+
local prev_aura_dir="\${_AURA_DIR:-}"
|
|
192
|
+
local aura_file=""
|
|
193
|
+
local check_dir="$PWD"
|
|
194
|
+
|
|
195
|
+
while [ "$check_dir" != "/" ]; do
|
|
196
|
+
if [ -f "$check_dir/.aura" ]; then
|
|
197
|
+
aura_file="$check_dir/.aura"
|
|
198
|
+
break
|
|
199
|
+
fi
|
|
200
|
+
check_dir="$(dirname "$check_dir")"
|
|
201
|
+
done
|
|
202
|
+
|
|
203
|
+
if [ -n "$aura_file" ]; then
|
|
204
|
+
local aura_dir="$(dirname "$aura_file")"
|
|
205
|
+
if [ "$aura_dir" != "$prev_aura_dir" ]; then
|
|
206
|
+
if [ -n "$prev_aura_dir" ] && [ -n "\${_AURA_VARS:-}" ]; then
|
|
207
|
+
for var in $_AURA_VARS; do unset "$var"; done
|
|
208
|
+
fi
|
|
209
|
+
local output
|
|
210
|
+
output="$(aura shell-hook resolve 2>/dev/null)"
|
|
211
|
+
if [ $? -eq 0 ] && [ -n "$output" ]; then
|
|
212
|
+
eval "$output"
|
|
213
|
+
export _AURA_DIR="$aura_dir"
|
|
214
|
+
fi
|
|
215
|
+
fi
|
|
216
|
+
elif [ -n "$prev_aura_dir" ]; then
|
|
217
|
+
if [ -n "\${_AURA_VARS:-}" ]; then
|
|
218
|
+
for var in $_AURA_VARS; do unset "$var"; done
|
|
219
|
+
fi
|
|
220
|
+
unset _AURA_DIR _AURA_VARS
|
|
221
|
+
fi
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if [[ ";\${PROMPT_COMMAND:-};" != *";_aura_hook;"* ]]; then
|
|
225
|
+
PROMPT_COMMAND="_aura_hook;\${PROMPT_COMMAND:-}"
|
|
226
|
+
fi
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function zshHook(): string {
|
|
231
|
+
return `# Aura shell hook — auto-load .aura env vars
|
|
232
|
+
_aura_hook() {
|
|
233
|
+
local prev_aura_dir="\${_AURA_DIR:-}"
|
|
234
|
+
local aura_file=""
|
|
235
|
+
local check_dir="$PWD"
|
|
236
|
+
|
|
237
|
+
while [[ "$check_dir" != "/" ]]; do
|
|
238
|
+
if [[ -f "$check_dir/.aura" ]]; then
|
|
239
|
+
aura_file="$check_dir/.aura"
|
|
240
|
+
break
|
|
241
|
+
fi
|
|
242
|
+
check_dir="$(dirname "$check_dir")"
|
|
243
|
+
done
|
|
244
|
+
|
|
245
|
+
if [[ -n "$aura_file" ]]; then
|
|
246
|
+
local aura_dir="$(dirname "$aura_file")"
|
|
247
|
+
if [[ "$aura_dir" != "$prev_aura_dir" ]]; then
|
|
248
|
+
if [[ -n "$prev_aura_dir" ]] && [[ -n "\${_AURA_VARS:-}" ]]; then
|
|
249
|
+
for var in \${(z)_AURA_VARS}; do unset "$var"; done
|
|
250
|
+
fi
|
|
251
|
+
local output
|
|
252
|
+
output="$(aura shell-hook resolve 2>/dev/null)"
|
|
253
|
+
if [[ $? -eq 0 ]] && [[ -n "$output" ]]; then
|
|
254
|
+
eval "$output"
|
|
255
|
+
export _AURA_DIR="$aura_dir"
|
|
256
|
+
fi
|
|
257
|
+
fi
|
|
258
|
+
elif [[ -n "$prev_aura_dir" ]]; then
|
|
259
|
+
if [[ -n "\${_AURA_VARS:-}" ]]; then
|
|
260
|
+
for var in \${(z)_AURA_VARS}; do unset "$var"; done
|
|
261
|
+
fi
|
|
262
|
+
unset _AURA_DIR _AURA_VARS
|
|
263
|
+
fi
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
autoload -U add-zsh-hook
|
|
267
|
+
add-zsh-hook chpwd _aura_hook
|
|
268
|
+
_aura_hook
|
|
269
|
+
`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ── Resolve (internal) ──
|
|
273
|
+
|
|
274
|
+
async function cmdResolve(): Promise<void> {
|
|
275
|
+
let dir = process.cwd();
|
|
276
|
+
let auraFile: string | null = null;
|
|
277
|
+
while (true) {
|
|
278
|
+
const candidate = path.join(dir, '.aura');
|
|
279
|
+
if (fs.existsSync(candidate)) { auraFile = candidate; break; }
|
|
280
|
+
const parent = path.dirname(dir);
|
|
281
|
+
if (parent === dir) break;
|
|
282
|
+
dir = parent;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!auraFile) process.exit(1);
|
|
286
|
+
|
|
287
|
+
const auraDir = path.dirname(auraFile);
|
|
288
|
+
const auraHash = hashFile(auraFile);
|
|
289
|
+
|
|
290
|
+
// Check whitelist
|
|
291
|
+
const allowed = loadAllowed();
|
|
292
|
+
const entry = allowed[auraDir];
|
|
293
|
+
if (!entry) {
|
|
294
|
+
console.error(`aura: ${auraDir} is not allowed. Run: aura shell-hook allow`);
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
if (entry.hash !== auraHash) {
|
|
298
|
+
console.error(`aura: .aura file changed in ${auraDir}. Run: aura shell-hook allow`);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Check cache
|
|
303
|
+
const cached = getCache(auraDir, auraHash);
|
|
304
|
+
if (cached) {
|
|
305
|
+
outputExports(cached);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Resolve from vault using shared module (audit finding #3)
|
|
310
|
+
const { parseAuraFile } = await import('./env');
|
|
311
|
+
const {
|
|
312
|
+
generateEphemeralKeypair,
|
|
313
|
+
bootstrapViaSocket,
|
|
314
|
+
bootstrapViaAuthRequest,
|
|
315
|
+
decryptWithPrivateKey,
|
|
316
|
+
createReadToken,
|
|
317
|
+
} = await import('../../lib/credential-transport');
|
|
318
|
+
const { serverUrl } = await import('../lib/http');
|
|
319
|
+
const { resolveMappings } = await import('../lib/credential-resolve');
|
|
320
|
+
|
|
321
|
+
const keypair = generateEphemeralKeypair();
|
|
322
|
+
const envToken = process.env.AURA_TOKEN;
|
|
323
|
+
const token = envToken || await (async () => {
|
|
324
|
+
try {
|
|
325
|
+
return await bootstrapViaSocket('shell-hook', keypair);
|
|
326
|
+
} catch (socketErr) {
|
|
327
|
+
return bootstrapViaAuthRequest(serverUrl(), 'shell-hook', keypair, {
|
|
328
|
+
onStatus: (message) => console.error(message),
|
|
329
|
+
}).catch((authErr) => {
|
|
330
|
+
throw new Error(`${getErrorMessage(socketErr)}\n${getErrorMessage(authErr)}`);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
})();
|
|
334
|
+
const base = serverUrl();
|
|
335
|
+
const readToken = await createReadToken(base, token, keypair, 'shell-hook-reader');
|
|
336
|
+
|
|
337
|
+
const mappings = parseAuraFile(auraFile);
|
|
338
|
+
const decryptFn = (encrypted: string) => decryptWithPrivateKey(encrypted, keypair.privateKeyPem);
|
|
339
|
+
const { resolved } = await resolveMappings(mappings, base, token, readToken, decryptFn);
|
|
340
|
+
|
|
341
|
+
const vars: Record<string, string> = Object.fromEntries(resolved);
|
|
342
|
+
setCache(auraDir, vars, auraHash);
|
|
343
|
+
outputExports(vars);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function outputExports(vars: Record<string, string>): void {
|
|
347
|
+
const varNames: string[] = [];
|
|
348
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
349
|
+
// Validate env var name to prevent injection via key (audit finding #6)
|
|
350
|
+
validateEnvVarName(key);
|
|
351
|
+
// Use ANSI-C $'...' quoting for safe shell escaping (audit finding #1)
|
|
352
|
+
console.log(`export ${key}=${escapeForShell(value)}`);
|
|
353
|
+
varNames.push(key);
|
|
354
|
+
}
|
|
355
|
+
if (varNames.length > 0) {
|
|
356
|
+
console.log(`export _AURA_VARS=${escapeForShell(varNames.join(' '))}`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// ── Install ──
|
|
361
|
+
|
|
362
|
+
function cmdInstall(): void {
|
|
363
|
+
const shell = path.basename(process.env.SHELL || 'bash');
|
|
364
|
+
let rcFile: string;
|
|
365
|
+
let hookCmd: string;
|
|
366
|
+
|
|
367
|
+
switch (shell) {
|
|
368
|
+
case 'zsh':
|
|
369
|
+
rcFile = path.join(os.homedir(), '.zshrc');
|
|
370
|
+
hookCmd = 'eval "$(aura shell-hook zsh)"';
|
|
371
|
+
break;
|
|
372
|
+
case 'bash':
|
|
373
|
+
rcFile = path.join(os.homedir(), '.bashrc');
|
|
374
|
+
hookCmd = 'eval "$(aura shell-hook bash)"';
|
|
375
|
+
break;
|
|
376
|
+
default:
|
|
377
|
+
console.error(`Unsupported shell: ${shell}. Manually add the hook to your rc file.`);
|
|
378
|
+
process.exit(1);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (fs.existsSync(rcFile)) {
|
|
383
|
+
const content = fs.readFileSync(rcFile, 'utf-8');
|
|
384
|
+
if (content.includes('aura shell-hook')) {
|
|
385
|
+
console.log(`Aura shell hook already installed in ${rcFile}`);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
fs.appendFileSync(rcFile, `\n# Aura shell hook — auto-load .aura env vars\n${hookCmd}\n`);
|
|
391
|
+
console.log(`✓ Added shell hook to ${rcFile}`);
|
|
392
|
+
console.log(` Restart your shell or run: source ${rcFile}`);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ── Allow / Deny / Status ──
|
|
396
|
+
|
|
397
|
+
function cmdAllow(dir?: string): void {
|
|
398
|
+
const targetDir = dir ? path.resolve(dir) : process.cwd();
|
|
399
|
+
const auraFile = path.join(targetDir, '.aura');
|
|
400
|
+
|
|
401
|
+
if (!fs.existsSync(auraFile)) {
|
|
402
|
+
console.error(`No .aura file found in ${targetDir}`);
|
|
403
|
+
process.exit(1);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const allowed = loadAllowed();
|
|
407
|
+
allowed[targetDir] = {
|
|
408
|
+
allowedAt: new Date().toISOString(),
|
|
409
|
+
hash: hashFile(auraFile),
|
|
410
|
+
};
|
|
411
|
+
saveAllowed(allowed);
|
|
412
|
+
console.log(`✓ Allowed ${targetDir}`);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function cmdDeny(dir?: string): void {
|
|
416
|
+
const targetDir = dir ? path.resolve(dir) : process.cwd();
|
|
417
|
+
const allowed = loadAllowed();
|
|
418
|
+
if (allowed[targetDir]) {
|
|
419
|
+
delete allowed[targetDir];
|
|
420
|
+
saveAllowed(allowed);
|
|
421
|
+
console.log(`✓ Denied ${targetDir}`);
|
|
422
|
+
} else {
|
|
423
|
+
console.log(`${targetDir} was not in the whitelist.`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function cmdStatus(): void {
|
|
428
|
+
const allowed = loadAllowed();
|
|
429
|
+
const entries = Object.entries(allowed);
|
|
430
|
+
|
|
431
|
+
if (entries.length === 0) {
|
|
432
|
+
console.log('No directories whitelisted.');
|
|
433
|
+
console.log('Run `aura shell-hook allow` in a directory with a .aura file.');
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
console.log('Whitelisted directories:\n');
|
|
438
|
+
for (const [dir, entry] of entries) {
|
|
439
|
+
const auraExists = fs.existsSync(path.join(dir, '.aura'));
|
|
440
|
+
let status = auraExists ? '✓' : '✗ .aura missing';
|
|
441
|
+
if (auraExists) {
|
|
442
|
+
const currentHash = hashFile(path.join(dir, '.aura'));
|
|
443
|
+
if (currentHash !== entry.hash) {
|
|
444
|
+
status = '⚠ .aura changed (run allow again)';
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
console.log(` ${status} ${dir}`);
|
|
448
|
+
console.log(` Allowed: ${entry.allowedAt}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ── Help ──
|
|
453
|
+
|
|
454
|
+
function showHelp(): void {
|
|
455
|
+
console.log(`
|
|
456
|
+
auramaxx shell-hook — Auto-load .aura env vars on cd
|
|
457
|
+
|
|
458
|
+
Usage:
|
|
459
|
+
aura shell-hook bash Output bash hook script
|
|
460
|
+
aura shell-hook zsh Output zsh hook script
|
|
461
|
+
aura shell-hook install Auto-detect shell, add to rc file
|
|
462
|
+
aura shell-hook allow Whitelist current directory
|
|
463
|
+
aura shell-hook deny Remove from whitelist
|
|
464
|
+
aura shell-hook status Show whitelist
|
|
465
|
+
|
|
466
|
+
Quick start:
|
|
467
|
+
aura shell-hook install # One-time setup
|
|
468
|
+
cd my-project # Has .aura file
|
|
469
|
+
aura shell-hook allow # Whitelist this project
|
|
470
|
+
cd ../ && cd my-project # Env vars auto-loaded!
|
|
471
|
+
`);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// ── Main ──
|
|
475
|
+
|
|
476
|
+
async function main(): Promise<void> {
|
|
477
|
+
const args = process.argv.slice(2);
|
|
478
|
+
const subcommand = args[0];
|
|
479
|
+
|
|
480
|
+
if (!subcommand || subcommand === '--help' || subcommand === '-h') {
|
|
481
|
+
showHelp();
|
|
482
|
+
process.exit(0);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
switch (subcommand) {
|
|
486
|
+
case 'bash':
|
|
487
|
+
process.stdout.write(bashHook());
|
|
488
|
+
return;
|
|
489
|
+
case 'zsh':
|
|
490
|
+
process.stdout.write(zshHook());
|
|
491
|
+
return;
|
|
492
|
+
case 'install':
|
|
493
|
+
return cmdInstall();
|
|
494
|
+
case 'allow':
|
|
495
|
+
return cmdAllow(args[1]);
|
|
496
|
+
case 'deny':
|
|
497
|
+
return cmdDeny(args[1]);
|
|
498
|
+
case 'status':
|
|
499
|
+
return cmdStatus();
|
|
500
|
+
case 'resolve':
|
|
501
|
+
return cmdResolve();
|
|
502
|
+
default:
|
|
503
|
+
console.error(`Unknown subcommand: ${subcommand}`);
|
|
504
|
+
showHelp();
|
|
505
|
+
process.exit(1);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
main().catch((err) => {
|
|
510
|
+
console.error(`Error: ${getErrorMessage(err)}`);
|
|
511
|
+
process.exit(1);
|
|
512
|
+
});
|