@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,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge communication mode resolver (SQ 0.8).
|
|
3
|
+
*
|
|
4
|
+
* Mode = the level of technical exposure Forge uses when
|
|
5
|
+
* talking to the user. Two values:
|
|
6
|
+
*
|
|
7
|
+
* didactico -- minimal tech detail, higher autonomy,
|
|
8
|
+
* consults only what is strictly necessary.
|
|
9
|
+
* tecnico -- full surface: diffs, tool calls, latencies,
|
|
10
|
+
* request ids; involves user in decisions.
|
|
11
|
+
*
|
|
12
|
+
* Precedence (highest wins):
|
|
13
|
+
* 1. YF_MODE env var
|
|
14
|
+
* 2. CLI flag (passed by callers, e.g. `yf chat --mode X`)
|
|
15
|
+
* 3. yujin.forge.json::mode in the project
|
|
16
|
+
* 4. DEFAULT (= didactico)
|
|
17
|
+
*
|
|
18
|
+
* Runtime changes (via `/modo` in chat) persist back to
|
|
19
|
+
* yujin.forge.json so the next launch picks it up.
|
|
20
|
+
*
|
|
21
|
+
* ASCII-only.
|
|
22
|
+
*/
|
|
23
|
+
import { promises as fs } from 'node:fs';
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
export const FORGE_MODES = ['didactico', 'tecnico'];
|
|
26
|
+
export const DEFAULT_MODE = 'didactico';
|
|
27
|
+
/** Project-config file at projectRoot. NB: `yf chat` reads
|
|
28
|
+
* `yujin.forge.json` already; we extend the same file. */
|
|
29
|
+
const PROJECT_CONFIG = 'yujin.forge.json';
|
|
30
|
+
function normalise(v) {
|
|
31
|
+
if (typeof v !== 'string')
|
|
32
|
+
return null;
|
|
33
|
+
const lower = v.trim().toLowerCase();
|
|
34
|
+
/* English aliases for the CLI / chat command. */
|
|
35
|
+
const map = {
|
|
36
|
+
'didactico': 'didactico',
|
|
37
|
+
'didactic': 'didactico',
|
|
38
|
+
'didact': 'didactico',
|
|
39
|
+
'd': 'didactico',
|
|
40
|
+
'tecnico': 'tecnico',
|
|
41
|
+
'tecnica': 'tecnico',
|
|
42
|
+
'technical': 'tecnico',
|
|
43
|
+
'tech': 'tecnico',
|
|
44
|
+
't': 'tecnico',
|
|
45
|
+
};
|
|
46
|
+
return map[lower] ?? null;
|
|
47
|
+
}
|
|
48
|
+
/** Resolve the effective mode for a process. */
|
|
49
|
+
export async function resolveMode(opts) {
|
|
50
|
+
/* 1. env */
|
|
51
|
+
const envRaw = opts.envValue ?? process.env.YF_MODE;
|
|
52
|
+
const fromEnv = normalise(envRaw);
|
|
53
|
+
if (fromEnv)
|
|
54
|
+
return { mode: fromEnv, source: 'env' };
|
|
55
|
+
/* 2. CLI */
|
|
56
|
+
const fromCli = normalise(opts.cliFlag);
|
|
57
|
+
if (fromCli)
|
|
58
|
+
return { mode: fromCli, source: 'cli' };
|
|
59
|
+
/* 3. project config */
|
|
60
|
+
const cfgPath = path.join(opts.projectRoot, PROJECT_CONFIG);
|
|
61
|
+
try {
|
|
62
|
+
const raw = await fs.readFile(cfgPath, 'utf-8');
|
|
63
|
+
const parsed = JSON.parse(raw);
|
|
64
|
+
const fromProject = normalise(parsed.mode);
|
|
65
|
+
if (fromProject)
|
|
66
|
+
return { mode: fromProject, source: 'project' };
|
|
67
|
+
}
|
|
68
|
+
catch { /* missing or bad -- fall through */ }
|
|
69
|
+
/* 4. default */
|
|
70
|
+
return { mode: DEFAULT_MODE, source: 'default' };
|
|
71
|
+
}
|
|
72
|
+
/** Persist `mode` into the project config file, creating it
|
|
73
|
+
* if missing. Existing fields are preserved. */
|
|
74
|
+
export async function persistMode(projectRoot, mode) {
|
|
75
|
+
const cfgPath = path.join(projectRoot, PROJECT_CONFIG);
|
|
76
|
+
let cfg = {};
|
|
77
|
+
try {
|
|
78
|
+
const raw = await fs.readFile(cfgPath, 'utf-8');
|
|
79
|
+
cfg = JSON.parse(raw);
|
|
80
|
+
if (!cfg || typeof cfg !== 'object')
|
|
81
|
+
cfg = {};
|
|
82
|
+
}
|
|
83
|
+
catch { /* create fresh */ }
|
|
84
|
+
cfg.mode = mode;
|
|
85
|
+
await fs.writeFile(cfgPath, JSON.stringify(cfg, null, 2), 'utf-8');
|
|
86
|
+
}
|
|
87
|
+
/** System-prompt suffix that the chat orchestrator injects
|
|
88
|
+
* into the Claude system role so the model adapts its tone
|
|
89
|
+
* + level of consultation to the user's mode. */
|
|
90
|
+
export function modePromptSuffix(mode) {
|
|
91
|
+
if (mode === 'didactico') {
|
|
92
|
+
return [
|
|
93
|
+
'',
|
|
94
|
+
'COMMUNICATION MODE: DIDACTIC.',
|
|
95
|
+
'- Use plain language, oriented at outcomes. Do NOT name',
|
|
96
|
+
' files, lines, classes, stack traces, or developer jargon',
|
|
97
|
+
' unless the user explicitly asks.',
|
|
98
|
+
'- Higher autonomy: decide internal technical details on',
|
|
99
|
+
' your own; consult the user ONLY when the decision affects',
|
|
100
|
+
' what they want to achieve (not how you achieve it).',
|
|
101
|
+
'- Progress updates summarise the result, not the steps.',
|
|
102
|
+
' ("registered the new user", not "wrote app/users.tsx").',
|
|
103
|
+
'- Errors framed as the next action: "could not read this',
|
|
104
|
+
' PDF, want to try another?" -- never raw stack traces.',
|
|
105
|
+
].join('\n');
|
|
106
|
+
}
|
|
107
|
+
/* tecnico */
|
|
108
|
+
return [
|
|
109
|
+
'',
|
|
110
|
+
'COMMUNICATION MODE: TECHNICAL.',
|
|
111
|
+
'- Expose the technical surface fully: files touched, lines',
|
|
112
|
+
' modified, tool calls dispatched, latencies, tokens, etc.',
|
|
113
|
+
'- Involve the user in technical decisions: present options',
|
|
114
|
+
' with trade-offs (cost, portability, complexity), ask which',
|
|
115
|
+
' one to take.',
|
|
116
|
+
'- Surface diffs before applying irreversible changes.',
|
|
117
|
+
'- Show stack traces + request ids on errors.',
|
|
118
|
+
'- Progress updates carry metadata: "scaffolded',
|
|
119
|
+
' `app/register.tsx`, 42 lines, 3 components".',
|
|
120
|
+
].join('\n');
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode.js","sourceRoot":"","sources":["../../src/core/mode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mobile pairing protocol -- CLI side.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors packages/nac3-rn/src/pairing.ts byte-for-byte on the
|
|
5
|
+
* crypto helpers (generatePairingCode / validatePairingCode /
|
|
6
|
+
* encryptPairing / decryptPairing / envelope helpers). The
|
|
7
|
+
* mobile side lives in the nac3-rn package; this copy is for
|
|
8
|
+
* the CLI which cannot import out-of-rootDir.
|
|
9
|
+
*
|
|
10
|
+
* Drift between the two sides is caught by
|
|
11
|
+
* tests/pairing-cross-impl.test.ts which encrypts on one side
|
|
12
|
+
* + decrypts on the other.
|
|
13
|
+
*
|
|
14
|
+
* ASCII-only. WebCrypto-only -- runs identically on Node 20+
|
|
15
|
+
* and React Native.
|
|
16
|
+
*/
|
|
17
|
+
export interface PairingPayload {
|
|
18
|
+
user_handle: string;
|
|
19
|
+
server_api_key: string;
|
|
20
|
+
hito4_base_url: string;
|
|
21
|
+
expires_at: string;
|
|
22
|
+
meta?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface PairingEnvelope {
|
|
25
|
+
v: 1;
|
|
26
|
+
salt: string;
|
|
27
|
+
iv: string;
|
|
28
|
+
ct: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function generatePairingCode(): string;
|
|
31
|
+
export declare function validatePairingCode(code: string): boolean;
|
|
32
|
+
export declare function encryptPairing(payload: PairingPayload, code: string): Promise<PairingEnvelope>;
|
|
33
|
+
export declare class PairingDecryptError extends Error {
|
|
34
|
+
readonly kind: 'bad_code' | 'expired' | 'malformed';
|
|
35
|
+
constructor(kind: 'bad_code' | 'expired' | 'malformed');
|
|
36
|
+
}
|
|
37
|
+
export declare function decryptPairing(envelope: PairingEnvelope, code: string): Promise<PairingPayload>;
|
|
38
|
+
export declare function envelopeToQrString(env: PairingEnvelope): string;
|
|
39
|
+
export declare function envelopeFromQrString(s: string): PairingEnvelope;
|
|
40
|
+
//# sourceMappingURL=pairing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/core/pairing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,CAAC,EAAE,CAAC,CAAC;IACL,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AA0BD,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAeD,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GACpC,OAAO,CAAC,eAAe,CAAC,CAa1B;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAChB,IAAI,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW;gBAA1C,IAAI,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW;CAGvE;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GACtC,OAAO,CAAC,cAAc,CAAC,CA+BzB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAE/D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,GAAG,eAAe,CAmB/D"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mobile pairing protocol -- CLI side.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors packages/nac3-rn/src/pairing.ts byte-for-byte on the
|
|
5
|
+
* crypto helpers (generatePairingCode / validatePairingCode /
|
|
6
|
+
* encryptPairing / decryptPairing / envelope helpers). The
|
|
7
|
+
* mobile side lives in the nac3-rn package; this copy is for
|
|
8
|
+
* the CLI which cannot import out-of-rootDir.
|
|
9
|
+
*
|
|
10
|
+
* Drift between the two sides is caught by
|
|
11
|
+
* tests/pairing-cross-impl.test.ts which encrypts on one side
|
|
12
|
+
* + decrypts on the other.
|
|
13
|
+
*
|
|
14
|
+
* ASCII-only. WebCrypto-only -- runs identically on Node 20+
|
|
15
|
+
* and React Native.
|
|
16
|
+
*/
|
|
17
|
+
const ENC = new TextEncoder();
|
|
18
|
+
const DEC = new TextDecoder();
|
|
19
|
+
const PBKDF2_ITERS = 200_000;
|
|
20
|
+
const KEY_BITS = 256;
|
|
21
|
+
const IV_BYTES = 12;
|
|
22
|
+
const SALT_BYTES = 16;
|
|
23
|
+
function bufToHex(buf) {
|
|
24
|
+
const view = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
|
|
25
|
+
let hex = '';
|
|
26
|
+
for (let i = 0; i < view.length; i++)
|
|
27
|
+
hex += view[i].toString(16).padStart(2, '0');
|
|
28
|
+
return hex;
|
|
29
|
+
}
|
|
30
|
+
function hexToBytes(hex) {
|
|
31
|
+
if (hex.length % 2 !== 0)
|
|
32
|
+
throw new Error('pairing: hex string has odd length');
|
|
33
|
+
const out = new Uint8Array(hex.length / 2);
|
|
34
|
+
for (let i = 0; i < out.length; i++) {
|
|
35
|
+
const byte = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
36
|
+
if (Number.isNaN(byte))
|
|
37
|
+
throw new Error('pairing: invalid hex');
|
|
38
|
+
out[i] = byte;
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
function randomBytes(n) {
|
|
43
|
+
const out = new Uint8Array(n);
|
|
44
|
+
crypto.getRandomValues(out);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
export function generatePairingCode() {
|
|
48
|
+
const n = Math.floor(Math.random() * 1_000_000);
|
|
49
|
+
return n.toString(10).padStart(6, '0');
|
|
50
|
+
}
|
|
51
|
+
export function validatePairingCode(code) {
|
|
52
|
+
return typeof code === 'string' && /^\d{6}$/.test(code);
|
|
53
|
+
}
|
|
54
|
+
async function deriveKey(code, salt) {
|
|
55
|
+
const baseKey = await crypto.subtle.importKey('raw', ENC.encode(code), { name: 'PBKDF2' }, false, ['deriveKey']);
|
|
56
|
+
return crypto.subtle.deriveKey({ name: 'PBKDF2', salt: salt, iterations: PBKDF2_ITERS, hash: 'SHA-256' }, baseKey, { name: 'AES-GCM', length: KEY_BITS }, false, ['encrypt', 'decrypt']);
|
|
57
|
+
}
|
|
58
|
+
export async function encryptPairing(payload, code) {
|
|
59
|
+
if (!validatePairingCode(code))
|
|
60
|
+
throw new Error('pairing: invalid code');
|
|
61
|
+
const salt = randomBytes(SALT_BYTES);
|
|
62
|
+
const iv = randomBytes(IV_BYTES);
|
|
63
|
+
const key = await deriveKey(code, salt);
|
|
64
|
+
const plain = ENC.encode(JSON.stringify(payload));
|
|
65
|
+
const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, plain);
|
|
66
|
+
return {
|
|
67
|
+
v: 1,
|
|
68
|
+
salt: bufToHex(salt),
|
|
69
|
+
iv: bufToHex(iv),
|
|
70
|
+
ct: bufToHex(new Uint8Array(ct)),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export class PairingDecryptError extends Error {
|
|
74
|
+
kind;
|
|
75
|
+
constructor(kind) {
|
|
76
|
+
super('pairing: ' + kind);
|
|
77
|
+
this.kind = kind;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export async function decryptPairing(envelope, code) {
|
|
81
|
+
if (!validatePairingCode(code))
|
|
82
|
+
throw new PairingDecryptError('bad_code');
|
|
83
|
+
if (envelope.v !== 1)
|
|
84
|
+
throw new PairingDecryptError('malformed');
|
|
85
|
+
let salt;
|
|
86
|
+
let iv;
|
|
87
|
+
let ct;
|
|
88
|
+
try {
|
|
89
|
+
salt = hexToBytes(envelope.salt);
|
|
90
|
+
iv = hexToBytes(envelope.iv);
|
|
91
|
+
ct = hexToBytes(envelope.ct);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
throw new PairingDecryptError('malformed');
|
|
95
|
+
}
|
|
96
|
+
const key = await deriveKey(code, salt);
|
|
97
|
+
let plain;
|
|
98
|
+
try {
|
|
99
|
+
plain = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ct);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
throw new PairingDecryptError('bad_code');
|
|
103
|
+
}
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = JSON.parse(DEC.decode(plain));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
throw new PairingDecryptError('malformed');
|
|
110
|
+
}
|
|
111
|
+
if (!parsed.user_handle || !parsed.server_api_key || !parsed.expires_at) {
|
|
112
|
+
throw new PairingDecryptError('malformed');
|
|
113
|
+
}
|
|
114
|
+
if (Date.parse(parsed.expires_at) < Date.now()) {
|
|
115
|
+
throw new PairingDecryptError('expired');
|
|
116
|
+
}
|
|
117
|
+
return parsed;
|
|
118
|
+
}
|
|
119
|
+
export function envelopeToQrString(env) {
|
|
120
|
+
return 'yfpair://' + Buffer.from(JSON.stringify(env), 'utf-8').toString('base64url');
|
|
121
|
+
}
|
|
122
|
+
export function envelopeFromQrString(s) {
|
|
123
|
+
if (!s.startsWith('yfpair://'))
|
|
124
|
+
throw new PairingDecryptError('malformed');
|
|
125
|
+
const b64 = s.slice('yfpair://'.length);
|
|
126
|
+
let json;
|
|
127
|
+
try {
|
|
128
|
+
json = Buffer.from(b64, 'base64url').toString('utf-8');
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
throw new PairingDecryptError('malformed');
|
|
132
|
+
}
|
|
133
|
+
let parsed;
|
|
134
|
+
try {
|
|
135
|
+
parsed = JSON.parse(json);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
throw new PairingDecryptError('malformed');
|
|
139
|
+
}
|
|
140
|
+
if (!parsed || typeof parsed !== 'object' || parsed.v !== 1) {
|
|
141
|
+
throw new PairingDecryptError('malformed');
|
|
142
|
+
}
|
|
143
|
+
return parsed;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../src/core/pairing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface PilotSetupState {
|
|
2
|
+
pilot_completed: boolean;
|
|
3
|
+
target_pending: boolean;
|
|
4
|
+
mode_pending: boolean;
|
|
5
|
+
}
|
|
6
|
+
/** Read the current pilot setup state. */
|
|
7
|
+
export declare function readPilotState(projectRoot: string): Promise<PilotSetupState>;
|
|
8
|
+
/** Mark Pilot setup as completed (also bumps the persisted
|
|
9
|
+
* yujin.forge.json with default values if any are missing). */
|
|
10
|
+
export declare function completePilotSetup(projectRoot: string, defaults?: {
|
|
11
|
+
target?: string;
|
|
12
|
+
mode?: string;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
/** System-prompt addendum that asks the user about target
|
|
15
|
+
* + mode in plain prose. Injected by buildSystemPrompt when
|
|
16
|
+
* pilot_completed is false. */
|
|
17
|
+
export declare function welcomePromptSuffix(state: PilotSetupState): string;
|
|
18
|
+
/** Decide whether to mark setup as complete after the first
|
|
19
|
+
* reply. Heuristic: if the user has answered both questions
|
|
20
|
+
* OR has skipped them by talking about something else, we
|
|
21
|
+
* flag completed (with defaults).
|
|
22
|
+
*
|
|
23
|
+
* The actual answer detection lives in the chat handler
|
|
24
|
+
* side; this function only encodes the decision shape. */
|
|
25
|
+
export declare function shouldAutoComplete(state: PilotSetupState, userMessage: string): {
|
|
26
|
+
complete: boolean;
|
|
27
|
+
reason: 'answered' | 'unrelated' | 'pending';
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=pilot_setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pilot_setup.d.ts","sourceRoot":"","sources":["../../src/core/pilot_setup.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAG,OAAO,CAAC;IACzB,YAAY,EAAK,OAAO,CAAC;CAC1B;AAED,0CAA0C;AAC1C,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAgBlF;AAED;gEACgE;AAChE,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,QAAQ,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;gCAEgC;AAChC,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAqBlE;AAED;;;;;;2DAM2D;AAC3D,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,SAAS,CAAA;CAAE,CAkBrE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pilot first-run setup (SQ 0.7 + 0.8 + 0.10 integration).
|
|
3
|
+
*
|
|
4
|
+
* When a user starts `yf chat` on a fresh project, Pilot
|
|
5
|
+
* MUST ask -- in natural language -- two questions:
|
|
6
|
+
* 1. target (responsive | mobile-only | desktop-only)
|
|
7
|
+
* 2. mode (didactico | tecnico)
|
|
8
|
+
*
|
|
9
|
+
* Per Pablo's decision (2026-05-26): use the chat-natural
|
|
10
|
+
* style (Option B) with a default-silencioso fallback. If
|
|
11
|
+
* the user replies about something else entirely, Forge
|
|
12
|
+
* defaults to `responsive` + `didactico` and continues --
|
|
13
|
+
* never blocks the conversation.
|
|
14
|
+
*
|
|
15
|
+
* State lives in `yujin.forge.json::pilot_completed` (boolean).
|
|
16
|
+
* Once true, the welcome prompt is skipped.
|
|
17
|
+
*
|
|
18
|
+
* ASCII-only.
|
|
19
|
+
*/
|
|
20
|
+
import { promises as fs } from 'node:fs';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
const CONFIG = 'yujin.forge.json';
|
|
23
|
+
/** Read the current pilot setup state. */
|
|
24
|
+
export async function readPilotState(projectRoot) {
|
|
25
|
+
try {
|
|
26
|
+
const raw = await fs.readFile(path.join(projectRoot, CONFIG), 'utf-8');
|
|
27
|
+
const parsed = JSON.parse(raw);
|
|
28
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
29
|
+
return { pilot_completed: false, target_pending: true, mode_pending: true };
|
|
30
|
+
}
|
|
31
|
+
const completed = parsed.pilot_completed === true;
|
|
32
|
+
return {
|
|
33
|
+
pilot_completed: completed,
|
|
34
|
+
target_pending: !parsed.target,
|
|
35
|
+
mode_pending: !parsed.mode,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return { pilot_completed: false, target_pending: true, mode_pending: true };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Mark Pilot setup as completed (also bumps the persisted
|
|
43
|
+
* yujin.forge.json with default values if any are missing). */
|
|
44
|
+
export async function completePilotSetup(projectRoot, defaults = {}) {
|
|
45
|
+
const cfgPath = path.join(projectRoot, CONFIG);
|
|
46
|
+
let cfg = {};
|
|
47
|
+
try {
|
|
48
|
+
const raw = await fs.readFile(cfgPath, 'utf-8');
|
|
49
|
+
cfg = JSON.parse(raw);
|
|
50
|
+
if (!cfg || typeof cfg !== 'object')
|
|
51
|
+
cfg = {};
|
|
52
|
+
}
|
|
53
|
+
catch { /* fresh */ }
|
|
54
|
+
cfg.pilot_completed = true;
|
|
55
|
+
if (!cfg.target && defaults.target)
|
|
56
|
+
cfg.target = defaults.target;
|
|
57
|
+
if (!cfg.mode && defaults.mode)
|
|
58
|
+
cfg.mode = defaults.mode;
|
|
59
|
+
/* Defaults of the defaults: responsive + didactico. */
|
|
60
|
+
if (!cfg.target)
|
|
61
|
+
cfg.target = 'responsive';
|
|
62
|
+
if (!cfg.mode)
|
|
63
|
+
cfg.mode = 'didactico';
|
|
64
|
+
await fs.writeFile(cfgPath, JSON.stringify(cfg, null, 2), 'utf-8');
|
|
65
|
+
}
|
|
66
|
+
/** System-prompt addendum that asks the user about target
|
|
67
|
+
* + mode in plain prose. Injected by buildSystemPrompt when
|
|
68
|
+
* pilot_completed is false. */
|
|
69
|
+
export function welcomePromptSuffix(state) {
|
|
70
|
+
if (state.pilot_completed)
|
|
71
|
+
return '';
|
|
72
|
+
const asks = [];
|
|
73
|
+
if (state.target_pending) {
|
|
74
|
+
asks.push('* la app, la queres responsive (desktop + mobile), solo mobile, o solo desktop?');
|
|
75
|
+
}
|
|
76
|
+
if (state.mode_pending) {
|
|
77
|
+
asks.push('* preferis que te hable en lenguaje simple (didactico) o que te muestre todos los detalles tecnicos (tecnico)?');
|
|
78
|
+
}
|
|
79
|
+
return [
|
|
80
|
+
'',
|
|
81
|
+
'FIRST-RUN PILOT SETUP (this is the first chat in this project).',
|
|
82
|
+
'On your very first reply, before answering the user, ask -- with one',
|
|
83
|
+
'short friendly sentence each -- the following:',
|
|
84
|
+
...asks,
|
|
85
|
+
'',
|
|
86
|
+
'If the user answers, persist via the /api/forge/target and',
|
|
87
|
+
'/api/forge/mode endpoints. If the user ignores the questions and',
|
|
88
|
+
'replies about something else, DO NOT insist -- continue with the',
|
|
89
|
+
'task they care about, and silently default to responsive + didactico.',
|
|
90
|
+
].join('\n');
|
|
91
|
+
}
|
|
92
|
+
/** Decide whether to mark setup as complete after the first
|
|
93
|
+
* reply. Heuristic: if the user has answered both questions
|
|
94
|
+
* OR has skipped them by talking about something else, we
|
|
95
|
+
* flag completed (with defaults).
|
|
96
|
+
*
|
|
97
|
+
* The actual answer detection lives in the chat handler
|
|
98
|
+
* side; this function only encodes the decision shape. */
|
|
99
|
+
export function shouldAutoComplete(state, userMessage) {
|
|
100
|
+
if (state.pilot_completed)
|
|
101
|
+
return { complete: true, reason: 'answered' };
|
|
102
|
+
const lower = userMessage.toLowerCase();
|
|
103
|
+
/* "Did the user mention target?" */
|
|
104
|
+
const targetKeywords = ['mobile', 'desktop', 'responsive', 'movil', 'celular', 'web', 'rn',
|
|
105
|
+
'react native', 'expo', 'pwa', 'ambos'];
|
|
106
|
+
const modeKeywords = ['didactico', 'didactic', 'tecnico', 'technical', 'modo'];
|
|
107
|
+
const mentionsTarget = targetKeywords.some((k) => lower.includes(k));
|
|
108
|
+
const mentionsMode = modeKeywords.some((k) => lower.includes(k));
|
|
109
|
+
if (mentionsTarget && mentionsMode) {
|
|
110
|
+
return { complete: true, reason: 'answered' };
|
|
111
|
+
}
|
|
112
|
+
/* If the user wrote >= 30 chars about something else, it's
|
|
113
|
+
* "unrelated" -> default silencioso. */
|
|
114
|
+
if (userMessage.trim().length >= 30 && !mentionsTarget && !mentionsMode) {
|
|
115
|
+
return { complete: true, reason: 'unrelated' };
|
|
116
|
+
}
|
|
117
|
+
return { complete: false, reason: 'pending' };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=pilot_setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pilot_setup.js","sourceRoot":"","sources":["../../src/core/pilot_setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License plans. Public-facing tiers: 'trial', 'paid',
|
|
3
|
+
* 'cancelled', 'free-public'. Internal-only (NOT advertised
|
|
4
|
+
* as a marketing tier): 'institutional' (Yujin grants to
|
|
5
|
+
* institutions), 'gifted' (other accommodations including
|
|
6
|
+
* but not limited to discapacidad).
|
|
7
|
+
*
|
|
8
|
+
* Billing model (Pablo 2026-05-26): TC captured at signup +
|
|
9
|
+
* 7 days free to cancel + day 8 = first charge. Implemented
|
|
10
|
+
* via Polar's `trial_period_days: 7` feature.
|
|
11
|
+
*/
|
|
12
|
+
export type LicensePlan = 'none' | 'trial' | 'paid' | 'cancelled' | 'free-public' | 'institutional' | 'gifted';
|
|
13
|
+
export interface LicenseCache {
|
|
14
|
+
version: 1;
|
|
15
|
+
plan: LicensePlan;
|
|
16
|
+
/** When the user attached the payment method (= start of
|
|
17
|
+
* the 7-day free cancel window). */
|
|
18
|
+
trial_started_at?: string;
|
|
19
|
+
/** When Polar will charge the first month (= trial_started_at + 7d). */
|
|
20
|
+
bills_first_on?: string;
|
|
21
|
+
/** Last day the user can cancel without being charged. */
|
|
22
|
+
cancel_grace_until?: string;
|
|
23
|
+
/** Polar subscription id (when plan in {trial, paid, cancelled}). */
|
|
24
|
+
subscription_id?: string;
|
|
25
|
+
/** Polar confirmed a payment method on file. */
|
|
26
|
+
payment_method_attached?: boolean;
|
|
27
|
+
/** Last successful server-side validation. */
|
|
28
|
+
last_validated_at?: string;
|
|
29
|
+
/** User-visible identifier (email / username). */
|
|
30
|
+
user_handle?: string;
|
|
31
|
+
/** ISO 8601 expiry for paid / cancelled / free-public.
|
|
32
|
+
* Null for institutional / gifted (perpetual until revoked). */
|
|
33
|
+
expires_at?: string | null;
|
|
34
|
+
}
|
|
35
|
+
/** Polar checkout URL -- the live checkout link for the
|
|
36
|
+
* Yujin Forge $10/mo subscription. Env override stays so devs
|
|
37
|
+
* can point at a test link without rebuilding.
|
|
38
|
+
*
|
|
39
|
+
* Polar checkout links accept `?customer_external_id=<handle>`
|
|
40
|
+
* as a query param -- buildCheckoutUrl appends it -- and the
|
|
41
|
+
* value persists into the subscription metadata, which the
|
|
42
|
+
* HITO 4 webhook handler reads via
|
|
43
|
+
* metadata.customer_external_id (with email fallback). */
|
|
44
|
+
export declare const POLAR_CHECKOUT_BASE: string;
|
|
45
|
+
/** Build a Polar checkout URL with the user's handle as a
|
|
46
|
+
* metadata field so we can correlate the subscription back
|
|
47
|
+
* to their license. */
|
|
48
|
+
export declare function buildCheckoutUrl(userHandle?: string): string;
|
|
49
|
+
/** Read the cached license. Returns a 'none' entry when no
|
|
50
|
+
* payment method has been captured yet -- the user is
|
|
51
|
+
* redirected to the Polar checkout. NO automatic trial
|
|
52
|
+
* seeding (TC-upfront model). */
|
|
53
|
+
export declare function readLicense(): Promise<LicenseCache>;
|
|
54
|
+
/** Persist the license cache. */
|
|
55
|
+
export declare function writeLicense(cache: LicenseCache): Promise<void>;
|
|
56
|
+
/** Helper: build a fresh trial license once the user
|
|
57
|
+
* attaches a payment method (typically called from the
|
|
58
|
+
* Polar webhook handler on `checkout.session.completed`). */
|
|
59
|
+
export declare function buildTrialLicense(opts: {
|
|
60
|
+
subscription_id: string;
|
|
61
|
+
user_handle?: string;
|
|
62
|
+
trial_days?: number;
|
|
63
|
+
}): LicenseCache;
|
|
64
|
+
/** Is the license currently active? Active = the user can
|
|
65
|
+
* use Forge right now. Includes trial (in grace), paid,
|
|
66
|
+
* cancelled-but-still-in-billing-period, institutional,
|
|
67
|
+
* gifted, and free-public. Excludes 'none' (no TC) and
|
|
68
|
+
* expired plans. */
|
|
69
|
+
export declare function isActive(cache: LicenseCache): boolean;
|
|
70
|
+
/** Days until the user gets charged (trial) or expires
|
|
71
|
+
* (paid/cancelled). Null when the plan has no time clock. */
|
|
72
|
+
export declare function daysUntilBillingOrExpiry(cache: LicenseCache): number | null;
|
|
73
|
+
/** Back-compat alias kept so existing callers don't break. */
|
|
74
|
+
export declare function daysRemaining(cache: LicenseCache): number | null;
|
|
75
|
+
/** Surface for `yf doctor` and the chat panel. ASCII-only.
|
|
76
|
+
* Internal-only plans (institutional, gifted) DO NOT
|
|
77
|
+
* surface the underlying reason -- they show a generic
|
|
78
|
+
* "free seat" message. Pablo's policy: no advertising
|
|
79
|
+
* discapacidad as a tier. */
|
|
80
|
+
export declare function describeLicense(cache: LicenseCache): string;
|
|
81
|
+
//# sourceMappingURL=polar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polar.d.ts","sourceRoot":"","sources":["../../src/core/polar.ts"],"names":[],"mappings":"AA2BA;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,OAAO,GACP,MAAM,GACN,WAAW,GACX,aAAa,GACb,eAAe,GACf,QAAQ,CAAC;AAEb,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB;yCACqC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;qEACiE;IACjE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAID;;;;;;;;2DAQ2D;AAC3D,eAAO,MAAM,mBAAmB,QAE6C,CAAC;AAE9E;;wBAEwB;AACxB,wBAAgB,gBAAgB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAI5D;AAOD;;;kCAGkC;AAClC,wBAAsB,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,CAWzD;AAED,iCAAiC;AACjC,wBAAsB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrE;AAED;;8DAE8D;AAC9D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,YAAY,CAcf;AAED;;;;qBAIqB;AACrB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAarD;AAED;8DAC8D;AAC9D,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAO3E;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAEhE;AAED;;;;8BAI8B;AAC9B,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CA6B3D"}
|