@nac3/forge-cli 0.2.0-alpha.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 +45 -0
- package/README.md +371 -0
- package/dist/bin/yf.d.ts +5 -0
- package/dist/bin/yf.d.ts.map +1 -0
- package/dist/bin/yf.js +86 -0
- package/dist/bin/yf.js.map +1 -0
- package/dist/chat/claude.d.ts +100 -0
- package/dist/chat/claude.d.ts.map +1 -0
- package/dist/chat/claude.js +228 -0
- package/dist/chat/claude.js.map +1 -0
- package/dist/chat/ingest_session.d.ts +97 -0
- package/dist/chat/ingest_session.d.ts.map +1 -0
- package/dist/chat/ingest_session.js +99 -0
- package/dist/chat/ingest_session.js.map +1 -0
- package/dist/chat/panel.d.ts +15 -0
- package/dist/chat/panel.d.ts.map +1 -0
- package/dist/chat/panel.js +1526 -0
- package/dist/chat/panel.js.map +1 -0
- package/dist/chat/persistence.d.ts +37 -0
- package/dist/chat/persistence.d.ts.map +1 -0
- package/dist/chat/persistence.js +91 -0
- package/dist/chat/persistence.js.map +1 -0
- package/dist/chat/server.d.ts +34 -0
- package/dist/chat/server.d.ts.map +1 -0
- package/dist/chat/server.js +1540 -0
- package/dist/chat/server.js.map +1 -0
- package/dist/chat/spec_extract.d.ts +35 -0
- package/dist/chat/spec_extract.d.ts.map +1 -0
- package/dist/chat/spec_extract.js +152 -0
- package/dist/chat/spec_extract.js.map +1 -0
- package/dist/chat/spec_plan.d.ts +65 -0
- package/dist/chat/spec_plan.d.ts.map +1 -0
- package/dist/chat/spec_plan.js +160 -0
- package/dist/chat/spec_plan.js.map +1 -0
- package/dist/chat/spec_scaffold.d.ts +95 -0
- package/dist/chat/spec_scaffold.d.ts.map +1 -0
- package/dist/chat/spec_scaffold.js +220 -0
- package/dist/chat/spec_scaffold.js.map +1 -0
- package/dist/chat/tools/git.d.ts +59 -0
- package/dist/chat/tools/git.d.ts.map +1 -0
- package/dist/chat/tools/git.js +313 -0
- package/dist/chat/tools/git.js.map +1 -0
- package/dist/chat/tools/github.d.ts +59 -0
- package/dist/chat/tools/github.d.ts.map +1 -0
- package/dist/chat/tools/github.js +310 -0
- package/dist/chat/tools/github.js.map +1 -0
- package/dist/chat/tools/lifecycle.d.ts +82 -0
- package/dist/chat/tools/lifecycle.d.ts.map +1 -0
- package/dist/chat/tools/lifecycle.js +295 -0
- package/dist/chat/tools/lifecycle.js.map +1 -0
- package/dist/chat/tools/manual.d.ts +26 -0
- package/dist/chat/tools/manual.d.ts.map +1 -0
- package/dist/chat/tools/manual.js +164 -0
- package/dist/chat/tools/manual.js.map +1 -0
- package/dist/chat/tools/reader.d.ts +80 -0
- package/dist/chat/tools/reader.d.ts.map +1 -0
- package/dist/chat/tools/reader.js +471 -0
- package/dist/chat/tools/reader.js.map +1 -0
- package/dist/chat/tools.d.ts +106 -0
- package/dist/chat/tools.d.ts.map +1 -0
- package/dist/chat/tools.js +587 -0
- package/dist/chat/tools.js.map +1 -0
- package/dist/codegen/e2e.d.ts +106 -0
- package/dist/codegen/e2e.d.ts.map +1 -0
- package/dist/codegen/e2e.js +931 -0
- package/dist/codegen/e2e.js.map +1 -0
- package/dist/codegen/v3_flow_emit.d.ts +70 -0
- package/dist/codegen/v3_flow_emit.d.ts.map +1 -0
- package/dist/codegen/v3_flow_emit.js +225 -0
- package/dist/codegen/v3_flow_emit.js.map +1 -0
- package/dist/commands/_stub.d.ts +2 -0
- package/dist/commands/_stub.d.ts.map +1 -0
- package/dist/commands/_stub.js +21 -0
- package/dist/commands/_stub.js.map +1 -0
- package/dist/commands/app.d.ts +31 -0
- package/dist/commands/app.d.ts.map +1 -0
- package/dist/commands/app.js +331 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/chat.d.ts +18 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +76 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/deploy.d.ts +21 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +121 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/doctor.d.ts +14 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +280 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/figma.d.ts +32 -0
- package/dist/commands/figma.d.ts.map +1 -0
- package/dist/commands/figma.js +141 -0
- package/dist/commands/figma.js.map +1 -0
- package/dist/commands/gen-flow-tests.d.ts +8 -0
- package/dist/commands/gen-flow-tests.d.ts.map +1 -0
- package/dist/commands/gen-flow-tests.js +78 -0
- package/dist/commands/gen-flow-tests.js.map +1 -0
- package/dist/commands/gen-tests.d.ts +9 -0
- package/dist/commands/gen-tests.d.ts.map +1 -0
- package/dist/commands/gen-tests.js +118 -0
- package/dist/commands/gen-tests.js.map +1 -0
- package/dist/commands/license.d.ts +14 -0
- package/dist/commands/license.d.ts.map +1 -0
- package/dist/commands/license.js +182 -0
- package/dist/commands/license.js.map +1 -0
- package/dist/commands/log.d.ts +19 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +101 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/migrate.d.ts +118 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +1410 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/mobile.d.ts +27 -0
- package/dist/commands/mobile.d.ts.map +1 -0
- package/dist/commands/mobile.js +90 -0
- package/dist/commands/mobile.js.map +1 -0
- package/dist/commands/new.d.ts +32 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +107 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/pilot.d.ts +8 -0
- package/dist/commands/pilot.d.ts.map +1 -0
- package/dist/commands/pilot.js +104 -0
- package/dist/commands/pilot.js.map +1 -0
- package/dist/commands/projects.d.ts +21 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +238 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/publish.d.ts +35 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +194 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/repo.d.ts +59 -0
- package/dist/commands/repo.d.ts.map +1 -0
- package/dist/commands/repo.js +178 -0
- package/dist/commands/repo.js.map +1 -0
- package/dist/commands/review-screens.d.ts +28 -0
- package/dist/commands/review-screens.d.ts.map +1 -0
- package/dist/commands/review-screens.js +345 -0
- package/dist/commands/review-screens.js.map +1 -0
- package/dist/commands/scenarios.d.ts +23 -0
- package/dist/commands/scenarios.d.ts.map +1 -0
- package/dist/commands/scenarios.js +304 -0
- package/dist/commands/scenarios.js.map +1 -0
- package/dist/commands/ship.d.ts +18 -0
- package/dist/commands/ship.d.ts.map +1 -0
- package/dist/commands/ship.js +41 -0
- package/dist/commands/ship.js.map +1 -0
- package/dist/commands/test.d.ts +29 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +62 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/tunnel.d.ts +22 -0
- package/dist/commands/tunnel.d.ts.map +1 -0
- package/dist/commands/tunnel.js +77 -0
- package/dist/commands/tunnel.js.map +1 -0
- package/dist/commands/validate.d.ts +14 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +51 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/vault.d.ts +32 -0
- package/dist/commands/vault.d.ts.map +1 -0
- package/dist/commands/vault.js +489 -0
- package/dist/commands/vault.js.map +1 -0
- package/dist/commands/voice.d.ts +16 -0
- package/dist/commands/voice.d.ts.map +1 -0
- package/dist/commands/voice.js +69 -0
- package/dist/commands/voice.js.map +1 -0
- package/dist/core/cascade_router.d.ts +90 -0
- package/dist/core/cascade_router.d.ts.map +1 -0
- package/dist/core/cascade_router.js +131 -0
- package/dist/core/cascade_router.js.map +1 -0
- package/dist/core/cf_tunnel.d.ts +52 -0
- package/dist/core/cf_tunnel.d.ts.map +1 -0
- package/dist/core/cf_tunnel.js +134 -0
- package/dist/core/cf_tunnel.js.map +1 -0
- package/dist/core/gha_dispatcher.d.ts +48 -0
- package/dist/core/gha_dispatcher.d.ts.map +1 -0
- package/dist/core/gha_dispatcher.js +198 -0
- package/dist/core/gha_dispatcher.js.map +1 -0
- package/dist/core/logger.d.ts +89 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +245 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mode.d.ts +26 -0
- package/dist/core/mode.d.ts.map +1 -0
- package/dist/core/mode.js +122 -0
- package/dist/core/mode.js.map +1 -0
- package/dist/core/pairing.d.ts +40 -0
- package/dist/core/pairing.d.ts.map +1 -0
- package/dist/core/pairing.js +145 -0
- package/dist/core/pairing.js.map +1 -0
- package/dist/core/pilot_setup.d.ts +29 -0
- package/dist/core/pilot_setup.d.ts.map +1 -0
- package/dist/core/pilot_setup.js +119 -0
- package/dist/core/pilot_setup.js.map +1 -0
- package/dist/core/polar.d.ts +81 -0
- package/dist/core/polar.d.ts.map +1 -0
- package/dist/core/polar.js +175 -0
- package/dist/core/polar.js.map +1 -0
- package/dist/core/project_picker.d.ts +56 -0
- package/dist/core/project_picker.d.ts.map +1 -0
- package/dist/core/project_picker.js +86 -0
- package/dist/core/project_picker.js.map +1 -0
- package/dist/core/projects.d.ts +58 -0
- package/dist/core/projects.d.ts.map +1 -0
- package/dist/core/projects.js +146 -0
- package/dist/core/projects.js.map +1 -0
- package/dist/core/projects_sync.d.ts +80 -0
- package/dist/core/projects_sync.d.ts.map +1 -0
- package/dist/core/projects_sync.js +278 -0
- package/dist/core/projects_sync.js.map +1 -0
- package/dist/core/remote_runner.d.ts +70 -0
- package/dist/core/remote_runner.d.ts.map +1 -0
- package/dist/core/remote_runner.js +133 -0
- package/dist/core/remote_runner.js.map +1 -0
- package/dist/core/repo_state.d.ts +24 -0
- package/dist/core/repo_state.d.ts.map +1 -0
- package/dist/core/repo_state.js +109 -0
- package/dist/core/repo_state.js.map +1 -0
- package/dist/core/target.d.ts +31 -0
- package/dist/core/target.d.ts.map +1 -0
- package/dist/core/target.js +121 -0
- package/dist/core/target.js.map +1 -0
- package/dist/deploy/aws.d.ts +43 -0
- package/dist/deploy/aws.d.ts.map +1 -0
- package/dist/deploy/aws.js +173 -0
- package/dist/deploy/aws.js.map +1 -0
- package/dist/figma/api.d.ts +35 -0
- package/dist/figma/api.d.ts.map +1 -0
- package/dist/figma/api.js +40 -0
- package/dist/figma/api.js.map +1 -0
- package/dist/figma/decorator.d.ts +74 -0
- package/dist/figma/decorator.d.ts.map +1 -0
- package/dist/figma/decorator.js +210 -0
- package/dist/figma/decorator.js.map +1 -0
- package/dist/figma/heuristics.d.ts +29 -0
- package/dist/figma/heuristics.d.ts.map +1 -0
- package/dist/figma/heuristics.js +110 -0
- package/dist/figma/heuristics.js.map +1 -0
- package/dist/figma/normalize.d.ts +33 -0
- package/dist/figma/normalize.d.ts.map +1 -0
- package/dist/figma/normalize.js +101 -0
- package/dist/figma/normalize.js.map +1 -0
- package/dist/figma/tokens.d.ts +23 -0
- package/dist/figma/tokens.d.ts.map +1 -0
- package/dist/figma/tokens.js +111 -0
- package/dist/figma/tokens.js.map +1 -0
- package/dist/figma/types.d.ts +118 -0
- package/dist/figma/types.d.ts.map +1 -0
- package/dist/figma/types.js +12 -0
- package/dist/figma/types.js.map +1 -0
- package/dist/i18n/index.d.ts +48 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +135 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/types.d.ts +52 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +85 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/lan/mdns_packet.d.ts +74 -0
- package/dist/lan/mdns_packet.d.ts.map +1 -0
- package/dist/lan/mdns_packet.js +247 -0
- package/dist/lan/mdns_packet.js.map +1 -0
- package/dist/lan/mdns_service.d.ts +102 -0
- package/dist/lan/mdns_service.d.ts.map +1 -0
- package/dist/lan/mdns_service.js +206 -0
- package/dist/lan/mdns_service.js.map +1 -0
- package/dist/license/activate.d.ts +33 -0
- package/dist/license/activate.d.ts.map +1 -0
- package/dist/license/activate.js +135 -0
- package/dist/license/activate.js.map +1 -0
- package/dist/license/fingerprint.d.ts +2 -0
- package/dist/license/fingerprint.d.ts.map +1 -0
- package/dist/license/fingerprint.js +29 -0
- package/dist/license/fingerprint.js.map +1 -0
- package/dist/license/hito4_client.d.ts +24 -0
- package/dist/license/hito4_client.d.ts.map +1 -0
- package/dist/license/hito4_client.js +103 -0
- package/dist/license/hito4_client.js.map +1 -0
- package/dist/license/index.d.ts +22 -0
- package/dist/license/index.d.ts.map +1 -0
- package/dist/license/index.js +125 -0
- package/dist/license/index.js.map +1 -0
- package/dist/license/types.d.ts +38 -0
- package/dist/license/types.d.ts.map +1 -0
- package/dist/license/types.js +9 -0
- package/dist/license/types.js.map +1 -0
- package/dist/migrate/ai-apply.d.ts +198 -0
- package/dist/migrate/ai-apply.d.ts.map +1 -0
- package/dist/migrate/ai-apply.js +833 -0
- package/dist/migrate/ai-apply.js.map +1 -0
- package/dist/migrate/ai-decorator.d.ts +87 -0
- package/dist/migrate/ai-decorator.d.ts.map +1 -0
- package/dist/migrate/ai-decorator.js +203 -0
- package/dist/migrate/ai-decorator.js.map +1 -0
- package/dist/migrate/apply.d.ts +28 -0
- package/dist/migrate/apply.d.ts.map +1 -0
- package/dist/migrate/apply.js +119 -0
- package/dist/migrate/apply.js.map +1 -0
- package/dist/migrate/audit.d.ts +9 -0
- package/dist/migrate/audit.d.ts.map +1 -0
- package/dist/migrate/audit.js +197 -0
- package/dist/migrate/audit.js.map +1 -0
- package/dist/migrate/diff.d.ts +28 -0
- package/dist/migrate/diff.d.ts.map +1 -0
- package/dist/migrate/diff.js +154 -0
- package/dist/migrate/diff.js.map +1 -0
- package/dist/migrate/html-orchestrator.d.ts +81 -0
- package/dist/migrate/html-orchestrator.d.ts.map +1 -0
- package/dist/migrate/html-orchestrator.js +233 -0
- package/dist/migrate/html-orchestrator.js.map +1 -0
- package/dist/migrate/html-walker.d.ts +93 -0
- package/dist/migrate/html-walker.d.ts.map +1 -0
- package/dist/migrate/html-walker.js +288 -0
- package/dist/migrate/html-walker.js.map +1 -0
- package/dist/migrate/js-template-walker.d.ts +118 -0
- package/dist/migrate/js-template-walker.d.ts.map +1 -0
- package/dist/migrate/js-template-walker.js +644 -0
- package/dist/migrate/js-template-walker.js.map +1 -0
- package/dist/migrate/manifest-validator.d.ts +30 -0
- package/dist/migrate/manifest-validator.d.ts.map +1 -0
- package/dist/migrate/manifest-validator.js +261 -0
- package/dist/migrate/manifest-validator.js.map +1 -0
- package/dist/migrate/overrides.d.ts +58 -0
- package/dist/migrate/overrides.d.ts.map +1 -0
- package/dist/migrate/overrides.js +193 -0
- package/dist/migrate/overrides.js.map +1 -0
- package/dist/migrate/plugin-scope.d.ts +42 -0
- package/dist/migrate/plugin-scope.d.ts.map +1 -0
- package/dist/migrate/plugin-scope.js +94 -0
- package/dist/migrate/plugin-scope.js.map +1 -0
- package/dist/migrate/types.d.ts +45 -0
- package/dist/migrate/types.d.ts.map +1 -0
- package/dist/migrate/types.js +9 -0
- package/dist/migrate/types.js.map +1 -0
- package/dist/migrate/verb-inference.d.ts +37 -0
- package/dist/migrate/verb-inference.d.ts.map +1 -0
- package/dist/migrate/verb-inference.js +274 -0
- package/dist/migrate/verb-inference.js.map +1 -0
- package/dist/nac3/attrs.d.ts +87 -0
- package/dist/nac3/attrs.d.ts.map +1 -0
- package/dist/nac3/attrs.js +134 -0
- package/dist/nac3/attrs.js.map +1 -0
- package/dist/nac3/scenario_dsl.d.ts +71 -0
- package/dist/nac3/scenario_dsl.d.ts.map +1 -0
- package/dist/nac3/scenario_dsl.js +191 -0
- package/dist/nac3/scenario_dsl.js.map +1 -0
- package/dist/nac3/tokens.d.ts +126 -0
- package/dist/nac3/tokens.d.ts.map +1 -0
- package/dist/nac3/tokens.js +138 -0
- package/dist/nac3/tokens.js.map +1 -0
- package/dist/reader/parsers/csv.d.ts +42 -0
- package/dist/reader/parsers/csv.d.ts.map +1 -0
- package/dist/reader/parsers/csv.js +221 -0
- package/dist/reader/parsers/csv.js.map +1 -0
- package/dist/reader/parsers/docx.d.ts +31 -0
- package/dist/reader/parsers/docx.d.ts.map +1 -0
- package/dist/reader/parsers/docx.js +51 -0
- package/dist/reader/parsers/docx.js.map +1 -0
- package/dist/reader/parsers/epub.d.ts +39 -0
- package/dist/reader/parsers/epub.d.ts.map +1 -0
- package/dist/reader/parsers/epub.js +265 -0
- package/dist/reader/parsers/epub.js.map +1 -0
- package/dist/reader/parsers/html.d.ts +40 -0
- package/dist/reader/parsers/html.d.ts.map +1 -0
- package/dist/reader/parsers/html.js +386 -0
- package/dist/reader/parsers/html.js.map +1 -0
- package/dist/reader/parsers/md.d.ts +30 -0
- package/dist/reader/parsers/md.d.ts.map +1 -0
- package/dist/reader/parsers/md.js +199 -0
- package/dist/reader/parsers/md.js.map +1 -0
- package/dist/reader/parsers/pdf.d.ts +39 -0
- package/dist/reader/parsers/pdf.d.ts.map +1 -0
- package/dist/reader/parsers/pdf.js +220 -0
- package/dist/reader/parsers/pdf.js.map +1 -0
- package/dist/reader/parsers/rtf.d.ts +37 -0
- package/dist/reader/parsers/rtf.d.ts.map +1 -0
- package/dist/reader/parsers/rtf.js +347 -0
- package/dist/reader/parsers/rtf.js.map +1 -0
- package/dist/reader/parsers/source.d.ts +32 -0
- package/dist/reader/parsers/source.d.ts.map +1 -0
- package/dist/reader/parsers/source.js +122 -0
- package/dist/reader/parsers/source.js.map +1 -0
- package/dist/reader/parsers/txt.d.ts +25 -0
- package/dist/reader/parsers/txt.d.ts.map +1 -0
- package/dist/reader/parsers/txt.js +56 -0
- package/dist/reader/parsers/txt.js.map +1 -0
- package/dist/reader/parsers/xlsx.d.ts +33 -0
- package/dist/reader/parsers/xlsx.d.ts.map +1 -0
- package/dist/reader/parsers/xlsx.js +143 -0
- package/dist/reader/parsers/xlsx.js.map +1 -0
- package/dist/reader/registry.d.ts +39 -0
- package/dist/reader/registry.d.ts.map +1 -0
- package/dist/reader/registry.js +172 -0
- package/dist/reader/registry.js.map +1 -0
- package/dist/reader/search.d.ts +27 -0
- package/dist/reader/search.d.ts.map +1 -0
- package/dist/reader/search.js +77 -0
- package/dist/reader/search.js.map +1 -0
- package/dist/reader/state.d.ts +56 -0
- package/dist/reader/state.d.ts.map +1 -0
- package/dist/reader/state.js +179 -0
- package/dist/reader/state.js.map +1 -0
- package/dist/reader/types.d.ts +119 -0
- package/dist/reader/types.d.ts.map +1 -0
- package/dist/reader/types.js +23 -0
- package/dist/reader/types.js.map +1 -0
- package/dist/ship/run.d.ts +26 -0
- package/dist/ship/run.d.ts.map +1 -0
- package/dist/ship/run.js +123 -0
- package/dist/ship/run.js.map +1 -0
- package/dist/template/index.d.ts +50 -0
- package/dist/template/index.d.ts.map +1 -0
- package/dist/template/index.js +140 -0
- package/dist/template/index.js.map +1 -0
- package/dist/ui/colors.d.ts +13 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +26 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/validate/index.d.ts +19 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +181 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/vault/catalog.d.ts +55 -0
- package/dist/vault/catalog.d.ts.map +1 -0
- package/dist/vault/catalog.js +424 -0
- package/dist/vault/catalog.js.map +1 -0
- package/dist/vault/crypto.d.ts +82 -0
- package/dist/vault/crypto.d.ts.map +1 -0
- package/dist/vault/crypto.js +173 -0
- package/dist/vault/crypto.js.map +1 -0
- package/dist/vault/git_askpass.d.ts +26 -0
- package/dist/vault/git_askpass.d.ts.map +1 -0
- package/dist/vault/git_askpass.js +104 -0
- package/dist/vault/git_askpass.js.map +1 -0
- package/dist/vault/migrator.d.ts +57 -0
- package/dist/vault/migrator.d.ts.map +1 -0
- package/dist/vault/migrator.js +204 -0
- package/dist/vault/migrator.js.map +1 -0
- package/dist/vault/redactor.d.ts +73 -0
- package/dist/vault/redactor.d.ts.map +1 -0
- package/dist/vault/redactor.js +182 -0
- package/dist/vault/redactor.js.map +1 -0
- package/dist/vault/store.d.ts +132 -0
- package/dist/vault/store.d.ts.map +1 -0
- package/dist/vault/store.js +335 -0
- package/dist/vault/store.js.map +1 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +8 -0
- package/dist/version.js.map +1 -0
- package/dist/voice/chunker.d.ts +43 -0
- package/dist/voice/chunker.d.ts.map +1 -0
- package/dist/voice/chunker.js +133 -0
- package/dist/voice/chunker.js.map +1 -0
- package/dist/voice/config.d.ts +14 -0
- package/dist/voice/config.d.ts.map +1 -0
- package/dist/voice/config.js +51 -0
- package/dist/voice/config.js.map +1 -0
- package/dist/voice/intents.d.ts +71 -0
- package/dist/voice/intents.d.ts.map +1 -0
- package/dist/voice/intents.js +0 -0
- package/dist/voice/intents.js.map +1 -0
- package/dist/voice/providers/elevenlabs.d.ts +53 -0
- package/dist/voice/providers/elevenlabs.d.ts.map +1 -0
- package/dist/voice/providers/elevenlabs.js +159 -0
- package/dist/voice/providers/elevenlabs.js.map +1 -0
- package/dist/voice/providers/google.d.ts +56 -0
- package/dist/voice/providers/google.d.ts.map +1 -0
- package/dist/voice/providers/google.js +253 -0
- package/dist/voice/providers/google.js.map +1 -0
- package/dist/voice/providers/whisper.d.ts +44 -0
- package/dist/voice/providers/whisper.d.ts.map +1 -0
- package/dist/voice/providers/whisper.js +179 -0
- package/dist/voice/providers/whisper.js.map +1 -0
- package/dist/voice/registry.d.ts +35 -0
- package/dist/voice/registry.d.ts.map +1 -0
- package/dist/voice/registry.js +48 -0
- package/dist/voice/registry.js.map +1 -0
- package/dist/voice/router.d.ts +62 -0
- package/dist/voice/router.d.ts.map +1 -0
- package/dist/voice/router.js +175 -0
- package/dist/voice/router.js.map +1 -0
- package/dist/voice/types.d.ts +116 -0
- package/dist/voice/types.d.ts.map +1 -0
- package/dist/voice/types.js +22 -0
- package/dist/voice/types.js.map +1 -0
- package/dist/voice/voiceprint/enrollment.d.ts +36 -0
- package/dist/voice/voiceprint/enrollment.d.ts.map +1 -0
- package/dist/voice/voiceprint/enrollment.js +71 -0
- package/dist/voice/voiceprint/enrollment.js.map +1 -0
- package/dist/voice/voiceprint/identify.d.ts +16 -0
- package/dist/voice/voiceprint/identify.d.ts.map +1 -0
- package/dist/voice/voiceprint/identify.js +20 -0
- package/dist/voice/voiceprint/identify.js.map +1 -0
- package/dist/voice/voiceprint/liveness.d.ts +90 -0
- package/dist/voice/voiceprint/liveness.d.ts.map +1 -0
- package/dist/voice/voiceprint/liveness.js +251 -0
- package/dist/voice/voiceprint/liveness.js.map +1 -0
- package/dist/voice/voiceprint/match.d.ts +54 -0
- package/dist/voice/voiceprint/match.d.ts.map +1 -0
- package/dist/voice/voiceprint/match.js +88 -0
- package/dist/voice/voiceprint/match.js.map +1 -0
- package/dist/voice/voiceprint/providers/local-mfcc-stub.d.ts +44 -0
- package/dist/voice/voiceprint/providers/local-mfcc-stub.d.ts.map +1 -0
- package/dist/voice/voiceprint/providers/local-mfcc-stub.js +92 -0
- package/dist/voice/voiceprint/providers/local-mfcc-stub.js.map +1 -0
- package/dist/voice/voiceprint/store.d.ts +60 -0
- package/dist/voice/voiceprint/store.d.ts.map +1 -0
- package/dist/voice/voiceprint/store.js +155 -0
- package/dist/voice/voiceprint/store.js.map +1 -0
- package/dist/voice/voiceprint/trust.d.ts +90 -0
- package/dist/voice/voiceprint/trust.d.ts.map +1 -0
- package/dist/voice/voiceprint/trust.js +150 -0
- package/dist/voice/voiceprint/trust.js.map +1 -0
- package/dist/voice/voiceprint/types.d.ts +100 -0
- package/dist/voice/voiceprint/types.d.ts.map +1 -0
- package/dist/voice/voiceprint/types.js +23 -0
- package/dist/voice/voiceprint/types.js.map +1 -0
- package/dist/voice/wake.d.ts +64 -0
- package/dist/voice/wake.d.ts.map +1 -0
- package/dist/voice/wake.js +143 -0
- package/dist/voice/wake.js.map +1 -0
- package/docs/manuals/manual.ar.html +91 -0
- package/docs/manuals/manual.de.html +100 -0
- package/docs/manuals/manual.en.html +118 -0
- package/docs/manuals/manual.es.html +120 -0
- package/docs/manuals/manual.fr.html +102 -0
- package/docs/manuals/manual.hi.html +93 -0
- package/docs/manuals/manual.it.html +93 -0
- package/docs/manuals/manual.ja.html +97 -0
- package/docs/manuals/manual.pt.html +103 -0
- package/docs/manuals/manual.zh.html +89 -0
- package/package.json +94 -0
- package/src/i18n/catalogs/ar.json +86 -0
- package/src/i18n/catalogs/de.json +86 -0
- package/src/i18n/catalogs/en.json +86 -0
- package/src/i18n/catalogs/es.json +86 -0
- package/src/i18n/catalogs/fr.json +86 -0
- package/src/i18n/catalogs/hi.json +86 -0
- package/src/i18n/catalogs/it.json +86 -0
- package/src/i18n/catalogs/ja.json +86 -0
- package/src/i18n/catalogs/pt.json +86 -0
- package/src/i18n/catalogs/zh.json +86 -0
- package/templates/react-app/README.md +43 -0
- package/templates/react-app/index.html +12 -0
- package/templates/react-app/package.json +35 -0
- package/templates/react-app/src/App.tsx +106 -0
- package/templates/react-app/src/main.tsx +21 -0
- package/templates/react-app/src/nac/manifest.ts +46 -0
- package/templates/react-app/src/styles.css +68 -0
- package/templates/react-app/tsconfig.json +19 -0
- package/templates/react-app/vite.config.ts +12 -0
- package/templates/react-app/yujin.forge.json +15 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault legacy migrator (PLAN V4).
|
|
3
|
+
*
|
|
4
|
+
* Walks a project root looking for `.env`, `.env.local`,
|
|
5
|
+
* `.env.production`, `config.json`, `secrets.json`, and the
|
|
6
|
+
* `.env*` family. Detects plaintext credentials -- both by
|
|
7
|
+
* key heuristics (KEY ends in `_TOKEN`, `_KEY`, `_SECRET`,
|
|
8
|
+
* `_PASSWORD`, etc.) AND by value pattern (using the same
|
|
9
|
+
* redactor patterns from SQ 0.11).
|
|
10
|
+
*
|
|
11
|
+
* For each finding the migrator proposes:
|
|
12
|
+
* - the candidate slot name (lowercased, sanitised)
|
|
13
|
+
* - the inferred kind from the catalog
|
|
14
|
+
* - the source file + line where it lives
|
|
15
|
+
*
|
|
16
|
+
* The CLI flow (`yf vault import-legacy`) lets the user
|
|
17
|
+
* confirm + applies the move atomically:
|
|
18
|
+
* - Encrypt + persist into the vault
|
|
19
|
+
* - Replace the value in the source file with
|
|
20
|
+
* `<from yf vault: SLOT_NAME>` (preserves the line for
|
|
21
|
+
* readability; the value is gone)
|
|
22
|
+
* - Append an audit entry
|
|
23
|
+
*
|
|
24
|
+
* This module exposes the PURE detection + classification
|
|
25
|
+
* functions; the CLI wires them with the Vault + filesystem.
|
|
26
|
+
* Tests mock with synthetic strings -- no real filesystem.
|
|
27
|
+
*
|
|
28
|
+
* ASCII-only.
|
|
29
|
+
*/
|
|
30
|
+
import { promises as fs } from 'node:fs';
|
|
31
|
+
import path from 'node:path';
|
|
32
|
+
import { redact } from './redactor.js';
|
|
33
|
+
import { inferKind } from './catalog.js';
|
|
34
|
+
/* Filenames that typically hold credentials. */
|
|
35
|
+
const DEFAULT_TARGETS = [
|
|
36
|
+
'.env',
|
|
37
|
+
'.env.local',
|
|
38
|
+
'.env.production',
|
|
39
|
+
'.env.development',
|
|
40
|
+
'.env.staging',
|
|
41
|
+
'config.json',
|
|
42
|
+
'secrets.json',
|
|
43
|
+
'keys.txt',
|
|
44
|
+
];
|
|
45
|
+
/* Env keys whose suffix usually indicates a credential. */
|
|
46
|
+
const CREDENTIAL_SUFFIX_RE = /(token|key|secret|password|passwd|credentials?|access|sid)\s*$/i;
|
|
47
|
+
/** Suggested vault slot name from an env-style key.
|
|
48
|
+
* Lowercase, snake_case, dropping the "AWS_" / "STRIPE_"
|
|
49
|
+
* prefix when it duplicates the catalog name. */
|
|
50
|
+
export function envKeyToSlot(envKey) {
|
|
51
|
+
const trimmed = envKey.trim();
|
|
52
|
+
const lower = trimmed.toLowerCase();
|
|
53
|
+
/* Direct catalog matches (return as-is). */
|
|
54
|
+
const direct = lower
|
|
55
|
+
.replace(/^aws_(access_key_id|secret_access_key)$/, 'aws_$1')
|
|
56
|
+
.replace(/^stripe_(secret|public)_key$/, 'stripe_$1_key');
|
|
57
|
+
/* Otherwise, just sanitise to vault rules: lowercase + [a-z0-9_-]
|
|
58
|
+
* starting with a letter. */
|
|
59
|
+
const sanitised = direct.replace(/[^a-z0-9_-]/g, '_').replace(/^[^a-z]+/, '');
|
|
60
|
+
return sanitised || 'unknown';
|
|
61
|
+
}
|
|
62
|
+
/** Parse a single env-style line `KEY=VALUE` (with optional
|
|
63
|
+
* comments + quoted values). Returns null when the line is
|
|
64
|
+
* blank, comment-only, or not key=value. */
|
|
65
|
+
export function parseEnvLine(line) {
|
|
66
|
+
if (!line || !line.trim() || line.trim().startsWith('#'))
|
|
67
|
+
return null;
|
|
68
|
+
/* Strip inline export prefix. */
|
|
69
|
+
const stripped = line.replace(/^\s*export\s+/, '');
|
|
70
|
+
const eq = stripped.indexOf('=');
|
|
71
|
+
if (eq < 0)
|
|
72
|
+
return null;
|
|
73
|
+
const key = stripped.slice(0, eq).trim();
|
|
74
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
|
|
75
|
+
return null;
|
|
76
|
+
let value = stripped.slice(eq + 1).trim();
|
|
77
|
+
/* Strip surrounding quotes. */
|
|
78
|
+
if ((value.startsWith('"') && value.endsWith('"'))
|
|
79
|
+
|| (value.startsWith("'") && value.endsWith("'"))) {
|
|
80
|
+
value = value.slice(1, -1);
|
|
81
|
+
}
|
|
82
|
+
/* Strip inline trailing comment after #. */
|
|
83
|
+
const hash = value.indexOf(' #');
|
|
84
|
+
if (hash > 0)
|
|
85
|
+
value = value.slice(0, hash).trim();
|
|
86
|
+
return { key, value };
|
|
87
|
+
}
|
|
88
|
+
/** Classify a parsed env line. Returns null when not
|
|
89
|
+
* credential-shaped.
|
|
90
|
+
*
|
|
91
|
+
* IMPORTANT: `original_line` on the returned finding is
|
|
92
|
+
* ALWAYS REDACTED. Safe to log, emit as JSON, surface in
|
|
93
|
+
* chat. The raw value never leaves the source file -- the
|
|
94
|
+
* applier reads it back from disk by file + line_number
|
|
95
|
+
* when migration is committed. */
|
|
96
|
+
export function classifyEnvEntry(parsed, file, lineNumber, originalLine) {
|
|
97
|
+
const keyLooksCred = CREDENTIAL_SUFFIX_RE.test(parsed.key);
|
|
98
|
+
const redaction = redact(parsed.value);
|
|
99
|
+
const valueLooksCred = redaction.hits.length > 0;
|
|
100
|
+
if (!keyLooksCred && !valueLooksCred)
|
|
101
|
+
return null;
|
|
102
|
+
const slot = envKeyToSlot(parsed.key);
|
|
103
|
+
/* If the redactor caught the value, use its redacted form;
|
|
104
|
+
* otherwise (pure key heuristic) compose KEY=****redacted****
|
|
105
|
+
* by hand so we never echo the raw value back. */
|
|
106
|
+
const lineRedaction = redact(originalLine);
|
|
107
|
+
const safeLine = lineRedaction.hits.length > 0
|
|
108
|
+
? lineRedaction.redacted
|
|
109
|
+
: parsed.key + '=****redacted****';
|
|
110
|
+
return {
|
|
111
|
+
suggested_slot: slot,
|
|
112
|
+
kind: inferKind(slot),
|
|
113
|
+
file,
|
|
114
|
+
line_number: lineNumber,
|
|
115
|
+
original_line: safeLine,
|
|
116
|
+
reason: keyLooksCred && valueLooksCred ? 'both'
|
|
117
|
+
: keyLooksCred ? 'key_heuristic'
|
|
118
|
+
: 'pattern',
|
|
119
|
+
...(valueLooksCred ? { pattern_hits: redaction.hits.map((h) => h.pattern) } : {}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** Scan a single text file for legacy credentials. Returns
|
|
123
|
+
* findings + the raw file content (so the caller can apply
|
|
124
|
+
* in-place replacement). */
|
|
125
|
+
export async function scanLegacyFile(abs, rel) {
|
|
126
|
+
let content;
|
|
127
|
+
try {
|
|
128
|
+
content = await fs.readFile(abs, 'utf-8');
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return { findings: [], content: '' };
|
|
132
|
+
}
|
|
133
|
+
const lines = content.split(/\r?\n/);
|
|
134
|
+
const findings = [];
|
|
135
|
+
for (let i = 0; i < lines.length; i++) {
|
|
136
|
+
const line = lines[i];
|
|
137
|
+
const parsed = parseEnvLine(line);
|
|
138
|
+
if (!parsed) {
|
|
139
|
+
/* For non-env files (JSON), fall back to a value-only
|
|
140
|
+
* scan that flags any line containing a redactor hit.
|
|
141
|
+
* The stored line is REDACTED (never raw). */
|
|
142
|
+
if (rel.endsWith('.json') || rel.endsWith('.txt')) {
|
|
143
|
+
const r = redact(line);
|
|
144
|
+
if (r.hits.length > 0) {
|
|
145
|
+
findings.push({
|
|
146
|
+
suggested_slot: 'imported_' + (i + 1),
|
|
147
|
+
kind: 'custom',
|
|
148
|
+
file: rel,
|
|
149
|
+
line_number: i + 1,
|
|
150
|
+
original_line: r.redacted,
|
|
151
|
+
reason: 'pattern',
|
|
152
|
+
pattern_hits: r.hits.map((h) => h.pattern),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const finding = classifyEnvEntry(parsed, rel, i + 1, line);
|
|
159
|
+
if (finding)
|
|
160
|
+
findings.push(finding);
|
|
161
|
+
}
|
|
162
|
+
return { findings, content };
|
|
163
|
+
}
|
|
164
|
+
/** Walk a project for legacy credential files. */
|
|
165
|
+
export async function scanLegacyProject(projectRoot, extraTargets = []) {
|
|
166
|
+
const targets = [...DEFAULT_TARGETS, ...extraTargets];
|
|
167
|
+
const findings = [];
|
|
168
|
+
for (const t of targets) {
|
|
169
|
+
const abs = path.join(projectRoot, t);
|
|
170
|
+
const stat = await fs.stat(abs).catch(() => null);
|
|
171
|
+
if (!stat || !stat.isFile())
|
|
172
|
+
continue;
|
|
173
|
+
const sf = await scanLegacyFile(abs, t);
|
|
174
|
+
findings.push(...sf.findings);
|
|
175
|
+
}
|
|
176
|
+
return findings;
|
|
177
|
+
}
|
|
178
|
+
/** Build a redacted copy of `content` -- replaces each
|
|
179
|
+
* flagged value with a placeholder pointing back to the
|
|
180
|
+
* vault slot. Idempotent (running twice does not double-
|
|
181
|
+
* replace). */
|
|
182
|
+
export function applyMigrationToContent(content, findings) {
|
|
183
|
+
if (findings.length === 0)
|
|
184
|
+
return content;
|
|
185
|
+
const lines = content.split(/\r?\n/);
|
|
186
|
+
for (const f of findings) {
|
|
187
|
+
const idx = f.line_number - 1;
|
|
188
|
+
if (idx < 0 || idx >= lines.length)
|
|
189
|
+
continue;
|
|
190
|
+
const original = lines[idx];
|
|
191
|
+
const parsed = parseEnvLine(original);
|
|
192
|
+
if (parsed) {
|
|
193
|
+
/* Preserve the key, swap the value for a vault
|
|
194
|
+
* reference comment. */
|
|
195
|
+
lines[idx] = parsed.key + '=<from yf vault: ' + f.suggested_slot + '>';
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
/* JSON / TXT line: rewrite to a comment that explains. */
|
|
199
|
+
lines[idx] = '/* yf vault migrated: see slot ' + f.suggested_slot + ' */';
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return lines.join('\n');
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=migrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrator.js","sourceRoot":"","sources":["../../src/vault/migrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,SAAS,EAAiB,MAAM,cAAc,CAAC;AAqBxD,gDAAgD;AAChD,MAAM,eAAe,GAAG;IACtB,MAAM;IACN,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,cAAc;IACd,aAAa;IACb,cAAc;IACd,UAAU;CACX,CAAC;AAEF,2DAA2D;AAC3D,MAAM,oBAAoB,GACxB,iEAAiE,CAAC;AAEpE;;kDAEkD;AAClD,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,4CAA4C;IAC5C,MAAM,MAAM,GAAG,KAAK;SACjB,OAAO,CAAC,yCAAyC,EAAE,QAAQ,CAAC;SAC5D,OAAO,CAAC,8BAA8B,EAAE,eAAe,CAAC,CAAC;IAC5D;iCAC6B;IAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9E,OAAO,SAAS,IAAI,SAAS,CAAC;AAChC,CAAC;AAED;;6CAE6C;AAC7C,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,iCAAiC;IACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,+BAA+B;IAC/B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;WAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACnD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,4CAA4C;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,IAAI,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AACxB,CAAC;AAED;;;;;;;mCAOmC;AACnC,MAAM,UAAU,gBAAgB,CAC9B,MAAsC,EACtC,IAAY,EACZ,UAAkB,EAClB,YAAoB;IAEpB,MAAM,YAAY,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAEjD,IAAI,CAAC,YAAY,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAElD,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACtC;;sDAEkD;IAClD,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAC5C,CAAC,CAAC,aAAa,CAAC,QAAQ;QACxB,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,mBAAmB,CAAC;IACrC,OAAO;QACL,cAAc,EAAE,IAAI;QACpB,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC;QACrB,IAAI;QACJ,WAAW,EAAE,UAAU;QACvB,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,YAAY,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM;YACzC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe;gBAChC,CAAC,CAAC,SAAS;QACjB,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClF,CAAC;AACJ,CAAC;AAED;;6BAE6B;AAC7B,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,GAAW;IAEX,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvC,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ;;0DAE8C;YAC9C,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBACvB,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,QAAQ,CAAC,IAAI,CAAC;wBACZ,cAAc,EAAE,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;wBACrC,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,GAAG;wBACT,WAAW,EAAE,CAAC,GAAG,CAAC;wBAClB,aAAa,EAAE,CAAC,CAAC,QAAQ;wBACzB,MAAM,EAAE,SAAS;wBACjB,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;qBAC3C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3D,IAAI,OAAO;YAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC;AAED,kDAAkD;AAClD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,eAAyB,EAAE;IAE3B,MAAM,OAAO,GAAG,CAAC,GAAG,eAAe,EAAE,GAAG,YAAY,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,SAAS;QACtC,MAAM,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;gBAGgB;AAChB,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,QAAyB;IAEzB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM;YAAE,SAAS;QAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,MAAM,EAAE,CAAC;YACX;oCACwB;YACxB,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,mBAAmB,GAAG,CAAC,CAAC,cAAc,GAAG,GAAG,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,0DAA0D;YAC1D,KAAK,CAAC,GAAG,CAAC,GAAG,iCAAiC,GAAG,CAAC,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5E,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token redactor (SQ 0.11).
|
|
3
|
+
*
|
|
4
|
+
* Pattern-based replacement of known secret shapes with
|
|
5
|
+
* `****redacted****` so credentials accidentally pasted in
|
|
6
|
+
* chat or written to logs do not survive in storage.
|
|
7
|
+
*
|
|
8
|
+
* The redactor errs on the side of false positives -- a
|
|
9
|
+
* non-secret value that looks like one of the patterns will
|
|
10
|
+
* also be redacted. The trade-off is acceptable; legitimate
|
|
11
|
+
* secrets must NEVER appear in chat / logs / argv even at the
|
|
12
|
+
* cost of occasionally over-redacting a benign string.
|
|
13
|
+
*
|
|
14
|
+
* Patterns covered:
|
|
15
|
+
* - GitHub tokens: ghp_*, gho_*, ghu_*, ghs_*, ghr_*,
|
|
16
|
+
* github_pat_*, gho_v1_*
|
|
17
|
+
* - npm classic tokens: npm_*
|
|
18
|
+
* - PyPI tokens: pypi-*
|
|
19
|
+
* - Anthropic: sk-ant-* (api03)
|
|
20
|
+
* - OpenAI: sk-* (project-scoped: sk-proj-*; legacy: sk-...)
|
|
21
|
+
* - AWS Access Key ID: AKIA[0-9A-Z]{16}
|
|
22
|
+
* - AWS Secret: 40-char base64 (heuristic, paired with AKIA)
|
|
23
|
+
* - Stripe: sk_live_*, sk_test_*, pk_live_*, pk_test_*,
|
|
24
|
+
* rk_live_*, rk_test_*, whsec_*
|
|
25
|
+
* - SendGrid: SG.[a-zA-Z0-9_-]{22}.[a-zA-Z0-9_-]{43}
|
|
26
|
+
* - Slack: xoxb-*, xoxp-*, xoxa-*, xoxr-*, xapp-*
|
|
27
|
+
* - Discord bot: M[A-Za-z0-9]{23}\.[A-Za-z0-9-_]{6}\.[A-Za-z0-9-_]{27}
|
|
28
|
+
* - Twilio: AC[0-9a-f]{32} (SID) and SK[0-9a-f]{32}
|
|
29
|
+
* - Linear: lin_api_*
|
|
30
|
+
* - Notion: secret_* or ntn_*
|
|
31
|
+
* - Figma: figd_* or figpat_*
|
|
32
|
+
* - JWT (best-effort): three-segment base64url
|
|
33
|
+
* - GCP service account JSON shape: detects "private_key":
|
|
34
|
+
* and redacts the key value.
|
|
35
|
+
* - Generic-looking git URL with embedded creds:
|
|
36
|
+
* `https?://x-access-token:TOKEN@`,
|
|
37
|
+
* `https?://[user]:[pass]@`.
|
|
38
|
+
*
|
|
39
|
+
* ASCII-only.
|
|
40
|
+
*/
|
|
41
|
+
export interface RedactionPattern {
|
|
42
|
+
/** Short name for telemetry / tests. */
|
|
43
|
+
name: string;
|
|
44
|
+
/** RegExp -- must use the `g` flag. */
|
|
45
|
+
re: RegExp;
|
|
46
|
+
/** Replacement string. The redactor swaps the whole match
|
|
47
|
+
* with this; sometimes a partial replacement is more useful
|
|
48
|
+
* (e.g. keep the URL prefix). When the replacement is a
|
|
49
|
+
* function, it is invoked with the standard String.replace
|
|
50
|
+
* arguments. */
|
|
51
|
+
replace: string | ((match: string, ...rest: string[]) => string);
|
|
52
|
+
}
|
|
53
|
+
export declare const REDACTION_PATTERNS: RedactionPattern[];
|
|
54
|
+
/**
|
|
55
|
+
* Run all redaction patterns against the input string.
|
|
56
|
+
* Returns the redacted text + a list of which patterns hit
|
|
57
|
+
* (the values themselves are NEVER returned -- only the
|
|
58
|
+
* pattern name + match count). */
|
|
59
|
+
export declare function redact(text: string): {
|
|
60
|
+
redacted: string;
|
|
61
|
+
hits: {
|
|
62
|
+
pattern: string;
|
|
63
|
+
count: number;
|
|
64
|
+
}[];
|
|
65
|
+
};
|
|
66
|
+
/** Convenience -- just the redacted text. */
|
|
67
|
+
export declare function redactText(text: string): string;
|
|
68
|
+
/** Deep walk over a JSON-like value and redact every string
|
|
69
|
+
* found. Returns a structurally identical value with strings
|
|
70
|
+
* replaced. Object keys are NOT redacted (only values) so
|
|
71
|
+
* the schema stays inspectable. */
|
|
72
|
+
export declare function redactDeep<T>(value: T): T;
|
|
73
|
+
//# sourceMappingURL=redactor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redactor.d.ts","sourceRoot":"","sources":["../../src/vault/redactor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX;;;;qBAIiB;IACjB,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC,CAAC;CAClE;AAID,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EA6GhD,CAAC;AAEF;;;;kCAIkC;AAClC,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAiBrG;AAED,6CAA6C;AAC7C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;oCAGoC;AACpC,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAWzC"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token redactor (SQ 0.11).
|
|
3
|
+
*
|
|
4
|
+
* Pattern-based replacement of known secret shapes with
|
|
5
|
+
* `****redacted****` so credentials accidentally pasted in
|
|
6
|
+
* chat or written to logs do not survive in storage.
|
|
7
|
+
*
|
|
8
|
+
* The redactor errs on the side of false positives -- a
|
|
9
|
+
* non-secret value that looks like one of the patterns will
|
|
10
|
+
* also be redacted. The trade-off is acceptable; legitimate
|
|
11
|
+
* secrets must NEVER appear in chat / logs / argv even at the
|
|
12
|
+
* cost of occasionally over-redacting a benign string.
|
|
13
|
+
*
|
|
14
|
+
* Patterns covered:
|
|
15
|
+
* - GitHub tokens: ghp_*, gho_*, ghu_*, ghs_*, ghr_*,
|
|
16
|
+
* github_pat_*, gho_v1_*
|
|
17
|
+
* - npm classic tokens: npm_*
|
|
18
|
+
* - PyPI tokens: pypi-*
|
|
19
|
+
* - Anthropic: sk-ant-* (api03)
|
|
20
|
+
* - OpenAI: sk-* (project-scoped: sk-proj-*; legacy: sk-...)
|
|
21
|
+
* - AWS Access Key ID: AKIA[0-9A-Z]{16}
|
|
22
|
+
* - AWS Secret: 40-char base64 (heuristic, paired with AKIA)
|
|
23
|
+
* - Stripe: sk_live_*, sk_test_*, pk_live_*, pk_test_*,
|
|
24
|
+
* rk_live_*, rk_test_*, whsec_*
|
|
25
|
+
* - SendGrid: SG.[a-zA-Z0-9_-]{22}.[a-zA-Z0-9_-]{43}
|
|
26
|
+
* - Slack: xoxb-*, xoxp-*, xoxa-*, xoxr-*, xapp-*
|
|
27
|
+
* - Discord bot: M[A-Za-z0-9]{23}\.[A-Za-z0-9-_]{6}\.[A-Za-z0-9-_]{27}
|
|
28
|
+
* - Twilio: AC[0-9a-f]{32} (SID) and SK[0-9a-f]{32}
|
|
29
|
+
* - Linear: lin_api_*
|
|
30
|
+
* - Notion: secret_* or ntn_*
|
|
31
|
+
* - Figma: figd_* or figpat_*
|
|
32
|
+
* - JWT (best-effort): three-segment base64url
|
|
33
|
+
* - GCP service account JSON shape: detects "private_key":
|
|
34
|
+
* and redacts the key value.
|
|
35
|
+
* - Generic-looking git URL with embedded creds:
|
|
36
|
+
* `https?://x-access-token:TOKEN@`,
|
|
37
|
+
* `https?://[user]:[pass]@`.
|
|
38
|
+
*
|
|
39
|
+
* ASCII-only.
|
|
40
|
+
*/
|
|
41
|
+
const REDACTED = '****redacted****';
|
|
42
|
+
export const REDACTION_PATTERNS = [
|
|
43
|
+
/* GitHub PATs + OAuth tokens. */
|
|
44
|
+
{ name: 'github_pat',
|
|
45
|
+
re: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{30,}\b/g,
|
|
46
|
+
replace: REDACTED },
|
|
47
|
+
{ name: 'github_fine_grained',
|
|
48
|
+
re: /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
|
|
49
|
+
replace: REDACTED },
|
|
50
|
+
/* npm classic automation tokens. */
|
|
51
|
+
{ name: 'npm_token',
|
|
52
|
+
re: /\bnpm_[A-Za-z0-9]{30,}\b/g,
|
|
53
|
+
replace: REDACTED },
|
|
54
|
+
/* PyPI. */
|
|
55
|
+
{ name: 'pypi_token',
|
|
56
|
+
re: /\bpypi-[A-Za-z0-9_-]{40,}\b/g,
|
|
57
|
+
replace: REDACTED },
|
|
58
|
+
/* Anthropic api03 keys. */
|
|
59
|
+
{ name: 'anthropic',
|
|
60
|
+
re: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,
|
|
61
|
+
replace: REDACTED },
|
|
62
|
+
/* OpenAI -- project and legacy. The classic shape (sk-XXXX)
|
|
63
|
+
* is greedy; we require >= 20 chars after the prefix to
|
|
64
|
+
* avoid matching CSS hex like `#ff0011`. */
|
|
65
|
+
{ name: 'openai_project',
|
|
66
|
+
re: /\bsk-proj-[A-Za-z0-9_-]{20,}\b/g,
|
|
67
|
+
replace: REDACTED },
|
|
68
|
+
{ name: 'openai_legacy',
|
|
69
|
+
re: /\bsk-[A-Za-z0-9]{20,}\b/g,
|
|
70
|
+
replace: REDACTED },
|
|
71
|
+
/* AWS Access Key ID. The matching secret is harder to
|
|
72
|
+
* detect alone (40 base64 chars) without false positives;
|
|
73
|
+
* we redact AKIA reliably and let the secret stay or be
|
|
74
|
+
* caught by context-aware redactors later. */
|
|
75
|
+
{ name: 'aws_access_key_id',
|
|
76
|
+
re: /\bAKIA[0-9A-Z]{16}\b/g,
|
|
77
|
+
replace: REDACTED },
|
|
78
|
+
/* Stripe. */
|
|
79
|
+
{ name: 'stripe_live_secret',
|
|
80
|
+
re: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g,
|
|
81
|
+
replace: REDACTED },
|
|
82
|
+
{ name: 'stripe_webhook_secret',
|
|
83
|
+
re: /\bwhsec_[A-Za-z0-9]{20,}\b/g,
|
|
84
|
+
replace: REDACTED },
|
|
85
|
+
/* SendGrid. The exact shape is 22 + dot + 43 but we accept
|
|
86
|
+
* 20+ each segment to tolerate format changes + test
|
|
87
|
+
* fixtures. */
|
|
88
|
+
{ name: 'sendgrid',
|
|
89
|
+
re: /\bSG\.[A-Za-z0-9_-]{20,30}\.[A-Za-z0-9_-]{40,50}\b/g,
|
|
90
|
+
replace: REDACTED },
|
|
91
|
+
/* Slack. */
|
|
92
|
+
{ name: 'slack',
|
|
93
|
+
re: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g,
|
|
94
|
+
replace: REDACTED },
|
|
95
|
+
{ name: 'slack_app',
|
|
96
|
+
re: /\bxapp-[A-Za-z0-9-]{10,}\b/g,
|
|
97
|
+
replace: REDACTED },
|
|
98
|
+
/* Discord bot token (3 segments of base64-ish text). */
|
|
99
|
+
{ name: 'discord_bot',
|
|
100
|
+
re: /\bM[A-Za-z0-9]{23,}\.[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{20,}\b/g,
|
|
101
|
+
replace: REDACTED },
|
|
102
|
+
/* Twilio Account SID + API Keys (ACxxxx / SKxxxx). */
|
|
103
|
+
{ name: 'twilio_id',
|
|
104
|
+
re: /\b(?:AC|SK)[0-9a-f]{32}\b/g,
|
|
105
|
+
replace: REDACTED },
|
|
106
|
+
/* Linear API. */
|
|
107
|
+
{ name: 'linear',
|
|
108
|
+
re: /\blin_api_[A-Za-z0-9_-]{20,}\b/g,
|
|
109
|
+
replace: REDACTED },
|
|
110
|
+
/* Notion. */
|
|
111
|
+
{ name: 'notion',
|
|
112
|
+
re: /\b(?:secret_|ntn_)[A-Za-z0-9]{20,}\b/g,
|
|
113
|
+
replace: REDACTED },
|
|
114
|
+
/* Figma. */
|
|
115
|
+
{ name: 'figma',
|
|
116
|
+
re: /\b(?:figd_|figpat_)[A-Za-z0-9_-]{20,}\b/g,
|
|
117
|
+
replace: REDACTED },
|
|
118
|
+
/* Generic git URLs with embedded credentials. We rewrite the
|
|
119
|
+
* middle, not the whole URL, so the (still useful) host
|
|
120
|
+
* and path stay readable. */
|
|
121
|
+
{ name: 'git_url_token',
|
|
122
|
+
re: /(https?:\/\/)x-access-token:[^@\s/]+@/g,
|
|
123
|
+
replace: (_m, scheme) => scheme + 'x-access-token:' + REDACTED + '@' },
|
|
124
|
+
{ name: 'git_url_user_pass',
|
|
125
|
+
re: /(https?:\/\/)([^@:\s/]+):([^@\s/]+)@/g,
|
|
126
|
+
replace: (_m, scheme, user) => scheme + user + ':' + REDACTED + '@' },
|
|
127
|
+
/* GCP service account JSON private_key field. */
|
|
128
|
+
{ name: 'gcp_private_key',
|
|
129
|
+
re: /"private_key"\s*:\s*"[^"]+"/g,
|
|
130
|
+
replace: '"private_key": "' + REDACTED + '"' },
|
|
131
|
+
/* JWT (best-effort: 3 segments base64url, last >= 20 chars). */
|
|
132
|
+
{ name: 'jwt',
|
|
133
|
+
re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
|
|
134
|
+
replace: REDACTED },
|
|
135
|
+
];
|
|
136
|
+
/**
|
|
137
|
+
* Run all redaction patterns against the input string.
|
|
138
|
+
* Returns the redacted text + a list of which patterns hit
|
|
139
|
+
* (the values themselves are NEVER returned -- only the
|
|
140
|
+
* pattern name + match count). */
|
|
141
|
+
export function redact(text) {
|
|
142
|
+
let out = text;
|
|
143
|
+
const hits = [];
|
|
144
|
+
for (const p of REDACTION_PATTERNS) {
|
|
145
|
+
/* Count matches first so we don't lose the count after
|
|
146
|
+
* replace(). String.matchAll requires a fresh iterator
|
|
147
|
+
* since the regex has the g flag. */
|
|
148
|
+
let count = 0;
|
|
149
|
+
p.re.lastIndex = 0;
|
|
150
|
+
for (const _ of out.matchAll(p.re))
|
|
151
|
+
count += 1;
|
|
152
|
+
if (count > 0) {
|
|
153
|
+
hits.push({ pattern: p.name, count });
|
|
154
|
+
p.re.lastIndex = 0;
|
|
155
|
+
out = out.replace(p.re, p.replace);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return { redacted: out, hits };
|
|
159
|
+
}
|
|
160
|
+
/** Convenience -- just the redacted text. */
|
|
161
|
+
export function redactText(text) {
|
|
162
|
+
return redact(text).redacted;
|
|
163
|
+
}
|
|
164
|
+
/** Deep walk over a JSON-like value and redact every string
|
|
165
|
+
* found. Returns a structurally identical value with strings
|
|
166
|
+
* replaced. Object keys are NOT redacted (only values) so
|
|
167
|
+
* the schema stays inspectable. */
|
|
168
|
+
export function redactDeep(value) {
|
|
169
|
+
if (typeof value === 'string')
|
|
170
|
+
return redactText(value);
|
|
171
|
+
if (Array.isArray(value))
|
|
172
|
+
return value.map((v) => redactDeep(v));
|
|
173
|
+
if (value && typeof value === 'object') {
|
|
174
|
+
const out = {};
|
|
175
|
+
for (const [k, v] of Object.entries(value)) {
|
|
176
|
+
out[k] = redactDeep(v);
|
|
177
|
+
}
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=redactor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redactor.js","sourceRoot":"","sources":["../../src/vault/redactor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault store: persistent, atomic, slot-based credential storage.
|
|
3
|
+
*
|
|
4
|
+
* File layout under the configured config directory (typically
|
|
5
|
+
* ~/.yujin-forge/):
|
|
6
|
+
*
|
|
7
|
+
* vault.salt 16 bytes of CSPRNG, written once per install
|
|
8
|
+
* vault.json JSON metadata + per-slot ciphertexts (base64)
|
|
9
|
+
*
|
|
10
|
+
* The salt is in its own file so it survives any corruption of
|
|
11
|
+
* vault.json -- worst case, the user re-enters their keys but does
|
|
12
|
+
* not need to regenerate the salt.
|
|
13
|
+
*
|
|
14
|
+
* Atomic writes: every persist writes to a `.tmp` sibling, fsyncs,
|
|
15
|
+
* then renames. Process death between write and rename leaves the
|
|
16
|
+
* old file intact; the orphan tmp is cleaned up on next open.
|
|
17
|
+
*
|
|
18
|
+
* Slot names: lowercase alphanumeric + underscore + hyphen,
|
|
19
|
+
* starting with a letter. Hard-rejected loudly otherwise.
|
|
20
|
+
*
|
|
21
|
+
* The list() surface returns metadata only: name, the first 4
|
|
22
|
+
* characters of the plaintext (so the user can confirm
|
|
23
|
+
* "yes, this is my key"), the plaintext length, and timestamps.
|
|
24
|
+
* Never returns ciphertext or plaintext beyond the prefix.
|
|
25
|
+
*
|
|
26
|
+
* Loud failures (per ROADMAP sec 12.2): every error path throws
|
|
27
|
+
* with a message explaining what went wrong.
|
|
28
|
+
*
|
|
29
|
+
* ASCII-only.
|
|
30
|
+
*/
|
|
31
|
+
import { type MachineFingerprint } from './crypto.js';
|
|
32
|
+
import { type SlotKind, type SlotTestResult } from './catalog.js';
|
|
33
|
+
export declare const VAULT_STORE_VERSION = 2;
|
|
34
|
+
export interface VaultSlotMetadata {
|
|
35
|
+
/** Slot identifier (e.g. "anthropic", "elevenlabs", "github_token"). */
|
|
36
|
+
name: string;
|
|
37
|
+
/** First 4 characters of the plaintext. Lets the user verify on
|
|
38
|
+
* set/list that the right key landed without exposing the full
|
|
39
|
+
* value. Stored unencrypted in vault.json; the threat-model
|
|
40
|
+
* trade-off is documented in the file header. */
|
|
41
|
+
prefix: string;
|
|
42
|
+
/** Plaintext length in characters. Sanity check + UX. */
|
|
43
|
+
length: number;
|
|
44
|
+
/** ISO 8601 first-write timestamp. */
|
|
45
|
+
created_at: string;
|
|
46
|
+
/** ISO 8601 last-write timestamp. */
|
|
47
|
+
updated_at: string;
|
|
48
|
+
/** Slot classification per SQ 0.11. v2+. */
|
|
49
|
+
kind: SlotKind;
|
|
50
|
+
/** Optional ISO 8601 expiry. Triggers rotation alerts when set. */
|
|
51
|
+
expiry?: string;
|
|
52
|
+
/** ISO 8601 timestamp of the last reachability test. */
|
|
53
|
+
last_test_at?: string;
|
|
54
|
+
/** Outcome of the last reachability test (true/false). */
|
|
55
|
+
last_test_ok?: boolean;
|
|
56
|
+
/** True when this slot name appears in the catalog (SLOT_CATALOG).
|
|
57
|
+
* Derived; not stored. */
|
|
58
|
+
in_catalog: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface VaultOpenOptions {
|
|
61
|
+
/** Absolute path to the config dir (typically ~/.yujin-forge). */
|
|
62
|
+
configDir: string;
|
|
63
|
+
/** Optional override of the machine fingerprint -- tests inject
|
|
64
|
+
* deterministic values to keep the suite offline. */
|
|
65
|
+
fingerprint?: MachineFingerprint;
|
|
66
|
+
}
|
|
67
|
+
export declare class Vault {
|
|
68
|
+
private readonly configDir;
|
|
69
|
+
private readonly salt;
|
|
70
|
+
private readonly key;
|
|
71
|
+
private readonly fingerprint;
|
|
72
|
+
private slots;
|
|
73
|
+
private constructor();
|
|
74
|
+
/**
|
|
75
|
+
* Open or create the vault at configDir.
|
|
76
|
+
* - Creates configDir if missing.
|
|
77
|
+
* - Reads or generates vault.salt.
|
|
78
|
+
* - Derives the master key.
|
|
79
|
+
* - Reads vault.json or starts with an empty slot set.
|
|
80
|
+
* - Cleans up any orphan vault.json.tmp from a previous crashed write.
|
|
81
|
+
*/
|
|
82
|
+
static open(opts: VaultOpenOptions): Promise<Vault>;
|
|
83
|
+
/** True when the slot has a stored value. */
|
|
84
|
+
has(slotName: string): boolean;
|
|
85
|
+
/** Slot metadata for every slot, sorted by name. Never returns
|
|
86
|
+
* ciphertext or plaintext beyond the 4-char prefix. */
|
|
87
|
+
list(): VaultSlotMetadata[];
|
|
88
|
+
/** Encrypt + persist a plaintext into the named slot. Overwrites
|
|
89
|
+
* if the slot already existed; the original created_at is
|
|
90
|
+
* preserved while updated_at is bumped.
|
|
91
|
+
*
|
|
92
|
+
* Options (all optional):
|
|
93
|
+
* - kind: override the kind (default = inferKind(slotName)).
|
|
94
|
+
* - expiry: ISO 8601 expiry. When omitted, the existing
|
|
95
|
+
* expiry is preserved (or cleared if you pass null).
|
|
96
|
+
*/
|
|
97
|
+
set(slotName: string, plaintext: string, opts?: SlotSetOptions): Promise<void>;
|
|
98
|
+
/** Decrypt and return the plaintext for a slot. Throws if the
|
|
99
|
+
* slot is missing or the ciphertext is corrupted. This is the
|
|
100
|
+
* ONLY path that surfaces plaintext, and it is server-side only
|
|
101
|
+
* -- never called from a route handler that returns to the
|
|
102
|
+
* browser. */
|
|
103
|
+
get(slotName: string): string;
|
|
104
|
+
/** Remove a slot. Returns true if the slot existed, false
|
|
105
|
+
* otherwise. Persists on success. */
|
|
106
|
+
remove(slotName: string): Promise<boolean>;
|
|
107
|
+
/** Rotate a slot: replace its plaintext with a new one. Equivalent
|
|
108
|
+
* to set() but expresses intent ("the old value is gone") in
|
|
109
|
+
* CLI surfaces. Same created_at preservation behaviour as set. */
|
|
110
|
+
rotate(slotName: string, newPlaintext: string): Promise<void>;
|
|
111
|
+
/** Probe the stored credential against the external service.
|
|
112
|
+
* Looks up the catalog entry for `slotName`. When no test
|
|
113
|
+
* function is defined, returns ok=true with detail "no probe
|
|
114
|
+
* registered" so the UI can still report something. Persists
|
|
115
|
+
* last_test_at + last_test_ok on the slot. */
|
|
116
|
+
test(slotName: string, opts?: {
|
|
117
|
+
timeoutMs?: number;
|
|
118
|
+
}): Promise<SlotTestResult>;
|
|
119
|
+
/** Total number of slots currently stored. */
|
|
120
|
+
size(): number;
|
|
121
|
+
/** Read-only view of the directory where this vault lives. */
|
|
122
|
+
configDirPath(): string;
|
|
123
|
+
private persist;
|
|
124
|
+
}
|
|
125
|
+
export interface SlotSetOptions {
|
|
126
|
+
/** Override the kind inferred from the slot name. */
|
|
127
|
+
kind?: SlotKind;
|
|
128
|
+
/** Set an ISO 8601 expiry. Pass `null` to clear an existing
|
|
129
|
+
* expiry; omit to preserve the current value. */
|
|
130
|
+
expiry?: string | null;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/vault/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,EAML,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,QAAQ,EAAE,KAAK,cAAc,EACnC,MAAM,cAAc,CAAC;AAMtB,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAOrC,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb;;;sDAGkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,IAAI,EAAE,QAAQ,CAAC;IACf,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;+BAC2B;IAC3B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB;0DACsD;IACtD,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAyBD,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,KAAK,CAAgC;IAE7C,OAAO;IAcP;;;;;;;OAOG;WACU,IAAI,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC;IA2FzD,6CAA6C;IAC7C,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI9B;4DACwD;IACxD,IAAI,IAAI,iBAAiB,EAAE;IAiB3B;;;;;;;;OAQG;IACG,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCxF;;;;mBAIe;IACf,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAS7B;0CACsC;IAChC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAShD;;uEAEmE;IAC7D,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE;;;;mDAI+C;IACzC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,cAAc,CAAC;IA0BxF,8CAA8C;IAC9C,IAAI,IAAI,MAAM;IAId,8DAA8D;IAC9D,aAAa,IAAI,MAAM;YAIT,OAAO;CAetB;AAED,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;sDACkD;IAClD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB"}
|