@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,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yujin Forge -- license activation + revocation.
|
|
3
|
+
*
|
|
4
|
+
* `yf license activate --key <jwt>` parses the JWT (without
|
|
5
|
+
* signature verification today -- the server key isn't published
|
|
6
|
+
* yet), extracts email + expiry, computes the machine fingerprint,
|
|
7
|
+
* and persists ~/.yujin-forge/license.json.
|
|
8
|
+
*
|
|
9
|
+
* `yf license revoke` deletes the license file so the user falls
|
|
10
|
+
* back to trial semantics.
|
|
11
|
+
*
|
|
12
|
+
* Server-side verification (POST to license.yujin.dev for
|
|
13
|
+
* signature + revocation check) is deferred. When wired, the same
|
|
14
|
+
* activate path will additionally verify against the public key
|
|
15
|
+
* and refuse activation if the server rejects the seat.
|
|
16
|
+
*
|
|
17
|
+
* JWT payload contract:
|
|
18
|
+
* {
|
|
19
|
+
* "sub": "<seat-id>",
|
|
20
|
+
* "email": "<email or null>",
|
|
21
|
+
* "exp": <unix-seconds or null for perpetual seats>,
|
|
22
|
+
* "iss": "license.yujin.dev",
|
|
23
|
+
* "iat": <unix-seconds>
|
|
24
|
+
* }
|
|
25
|
+
*/
|
|
26
|
+
import { promises as fs } from 'node:fs';
|
|
27
|
+
import path from 'node:path';
|
|
28
|
+
import { configDir } from './index.js';
|
|
29
|
+
import { machineFingerprint } from './fingerprint.js';
|
|
30
|
+
export class InvalidLicenseKeyError extends Error {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = 'InvalidLicenseKeyError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse a JWT without verifying the signature. Throws
|
|
38
|
+
* InvalidLicenseKeyError on any shape error so the caller can
|
|
39
|
+
* print a precise hint instead of a stack trace.
|
|
40
|
+
*/
|
|
41
|
+
export function parseJwt(raw) {
|
|
42
|
+
const trimmed = raw.trim();
|
|
43
|
+
if (trimmed === '') {
|
|
44
|
+
throw new InvalidLicenseKeyError('license key is empty');
|
|
45
|
+
}
|
|
46
|
+
const parts = trimmed.split('.');
|
|
47
|
+
if (parts.length !== 3) {
|
|
48
|
+
throw new InvalidLicenseKeyError('license key must be a JWT (3 dot-separated parts)');
|
|
49
|
+
}
|
|
50
|
+
const [h, p] = parts;
|
|
51
|
+
let header;
|
|
52
|
+
let payload;
|
|
53
|
+
try {
|
|
54
|
+
header = JSON.parse(base64UrlDecode(h));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new InvalidLicenseKeyError('license key header is not valid base64url JSON');
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
payload = JSON.parse(base64UrlDecode(p));
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
throw new InvalidLicenseKeyError('license key payload is not valid base64url JSON');
|
|
64
|
+
}
|
|
65
|
+
if (!isPlainObject(header) || !isPlainObject(payload)) {
|
|
66
|
+
throw new InvalidLicenseKeyError('license key header or payload is not an object');
|
|
67
|
+
}
|
|
68
|
+
return { header, payload, raw: trimmed };
|
|
69
|
+
}
|
|
70
|
+
function isPlainObject(v) {
|
|
71
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
72
|
+
}
|
|
73
|
+
function base64UrlDecode(s) {
|
|
74
|
+
const pad = s.length % 4 === 0 ? '' : '='.repeat(4 - (s.length % 4));
|
|
75
|
+
const normalised = s.replace(/-/g, '+').replace(/_/g, '/') + pad;
|
|
76
|
+
return Buffer.from(normalised, 'base64').toString('utf-8');
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Activate a license key on this machine. Writes
|
|
80
|
+
* ~/.yujin-forge/license.json after extracting the relevant claims.
|
|
81
|
+
*
|
|
82
|
+
* Throws InvalidLicenseKeyError on shape / freshness errors.
|
|
83
|
+
* Throws plain Error on filesystem issues.
|
|
84
|
+
*/
|
|
85
|
+
export async function activate(rawKey) {
|
|
86
|
+
const parsed = parseJwt(rawKey);
|
|
87
|
+
const payload = parsed.payload;
|
|
88
|
+
const sub = payload['sub'];
|
|
89
|
+
if (typeof sub !== 'string' || sub.length === 0) {
|
|
90
|
+
throw new InvalidLicenseKeyError("license key payload missing 'sub'");
|
|
91
|
+
}
|
|
92
|
+
const expRaw = payload['exp'];
|
|
93
|
+
let expiresAt = null;
|
|
94
|
+
if (expRaw != null) {
|
|
95
|
+
if (typeof expRaw !== 'number') {
|
|
96
|
+
throw new InvalidLicenseKeyError("license key payload 'exp' must be a number (unix seconds) or null");
|
|
97
|
+
}
|
|
98
|
+
if (expRaw * 1000 <= Date.now()) {
|
|
99
|
+
throw new InvalidLicenseKeyError('license key is already expired');
|
|
100
|
+
}
|
|
101
|
+
expiresAt = new Date(expRaw * 1000).toISOString();
|
|
102
|
+
}
|
|
103
|
+
const emailRaw = payload['email'];
|
|
104
|
+
const email = typeof emailRaw === 'string' && emailRaw.length > 0
|
|
105
|
+
? emailRaw
|
|
106
|
+
: null;
|
|
107
|
+
const seat = {
|
|
108
|
+
token: rawKey.trim(),
|
|
109
|
+
expiresAt,
|
|
110
|
+
lastCheckedAt: new Date().toISOString(),
|
|
111
|
+
email,
|
|
112
|
+
machineFingerprint: machineFingerprint(),
|
|
113
|
+
};
|
|
114
|
+
await fs.mkdir(configDir(), { recursive: true });
|
|
115
|
+
const filePath = path.join(configDir(), 'license.json');
|
|
116
|
+
await fs.writeFile(filePath, JSON.stringify(seat, null, 2), 'utf-8');
|
|
117
|
+
return { seat, path: filePath };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Remove the local license cache. Returns true if a file was
|
|
121
|
+
* deleted, false if no license was installed.
|
|
122
|
+
*/
|
|
123
|
+
export async function revoke() {
|
|
124
|
+
const filePath = path.join(configDir(), 'license.json');
|
|
125
|
+
try {
|
|
126
|
+
await fs.unlink(filePath);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (err.code === 'ENOENT')
|
|
131
|
+
return false;
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=activate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src/license/activate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/license/fingerprint.ts"],"names":[],"mappings":"AAkBA,wBAAgB,kBAAkB,IAAI,MAAM,CAU3C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yujin Forge -- machine fingerprint.
|
|
3
|
+
*
|
|
4
|
+
* Deterministic identifier the license server pins seats to.
|
|
5
|
+
* Inputs are stable across boots + non-PII:
|
|
6
|
+
* - hostname (os.hostname())
|
|
7
|
+
* - platform (process.platform)
|
|
8
|
+
* - arch (process.arch)
|
|
9
|
+
* - $HOME basename (signals 'pablo' vs 'root' but doesn't leak the path)
|
|
10
|
+
*
|
|
11
|
+
* We deliberately AVOID MAC addresses + serial numbers -- the
|
|
12
|
+
* value is to bind a license to "this machine for this user",
|
|
13
|
+
* not to identify the hardware.
|
|
14
|
+
*/
|
|
15
|
+
import { createHash } from 'node:crypto';
|
|
16
|
+
import os from 'node:os';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
export function machineFingerprint() {
|
|
19
|
+
const homeBase = path.basename(os.homedir() || '');
|
|
20
|
+
const raw = [
|
|
21
|
+
'yujin-forge/v1',
|
|
22
|
+
os.hostname(),
|
|
23
|
+
process.platform,
|
|
24
|
+
process.arch,
|
|
25
|
+
homeBase,
|
|
26
|
+
].join('|');
|
|
27
|
+
return createHash('sha256').update(raw).digest('hex').slice(0, 32);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/license/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG;QACV,gBAAgB;QAChB,EAAE,CAAC,QAAQ,EAAE;QACb,OAAO,CAAC,QAAQ;QAChB,OAAO,CAAC,IAAI;QACZ,QAAQ;KACT,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Vault } from '../vault/store.js';
|
|
2
|
+
export declare const HITO4_BASE_URL: string;
|
|
3
|
+
export interface Hito4ClientDeps {
|
|
4
|
+
fetchImpl?: typeof fetch;
|
|
5
|
+
vaultOpener?: () => Promise<Vault>;
|
|
6
|
+
/** Provides the user_handle. Defaults to reading
|
|
7
|
+
* ~/.yujin-forge/license.json (Polar cache). */
|
|
8
|
+
handleProvider?: () => Promise<string>;
|
|
9
|
+
/** Override the base URL for tests. */
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function signBearer(secret: string, handle: string, ts?: number): string;
|
|
13
|
+
export interface FlowCallResult {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
status: number;
|
|
16
|
+
body: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/** Call a HITO 4 flow. Returns the raw server response (no
|
|
19
|
+
* retry / no backoff -- callers can decide). */
|
|
20
|
+
export declare function callFlow(flow: string, input: unknown, deps?: Hito4ClientDeps): Promise<FlowCallResult>;
|
|
21
|
+
/** Pull the up-to-date license row from the server. The CLI's
|
|
22
|
+
* Polar cache is then refreshed with the result. */
|
|
23
|
+
export declare function fetchServerLicense(deps?: Hito4ClientDeps): Promise<FlowCallResult>;
|
|
24
|
+
//# sourceMappingURL=hito4_client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hito4_client.d.ts","sourceRoot":"","sources":["../../src/license/hito4_client.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAI1C,eAAO,MAAM,cAAc,QAA8E,CAAC;AAG1G,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC;qDACiD;IACjD,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA+BD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,GAAE,MAAmB,GAAG,MAAM,CAG1F;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;iDACiD;AACjD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,eAAoB,GACvD,OAAO,CAAC,cAAc,CAAC,CAmBzB;AAED;qDACqD;AACrD,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAc5F"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HITO 4 client -- HMAC-signed calls from the CLI to the
|
|
3
|
+
* Yujin Forge server. Alpha default route is
|
|
4
|
+
* yujin-hito4.yujinapp.workers.dev (workers.dev); the
|
|
5
|
+
* prompts.yujin.app custom domain replaces it once CF DNS is
|
|
6
|
+
* configured. Callers can override via YF_HITO4_BASE_URL env.
|
|
7
|
+
*
|
|
8
|
+
* The CLI signs every request with the SERVER_API_KEY shared
|
|
9
|
+
* secret. The secret is provisioned to each tenant at Forge
|
|
10
|
+
* install time + lives in a dedicated vault slot
|
|
11
|
+
* (`yf_server_api_key`). It is NEVER bundled into the
|
|
12
|
+
* published package; missing secret -> hard error pointing the
|
|
13
|
+
* user to `yf vault set yf_server_api_key`.
|
|
14
|
+
*
|
|
15
|
+
* The user_handle ridding the bearer must match the handle on
|
|
16
|
+
* the local Polar license cache; the server uses it to lookup
|
|
17
|
+
* the entitlement row.
|
|
18
|
+
*
|
|
19
|
+
* ASCII-only.
|
|
20
|
+
*/
|
|
21
|
+
import { createHmac } from 'node:crypto';
|
|
22
|
+
import { Vault } from '../vault/store.js';
|
|
23
|
+
import { configDir } from './index.js';
|
|
24
|
+
import { readLicense } from '../core/polar.js';
|
|
25
|
+
export const HITO4_BASE_URL = process.env.YF_HITO4_BASE_URL ?? 'https://yujin-hito4.yujinapp.workers.dev';
|
|
26
|
+
const SECRET_SLOT = 'yf_server_api_key';
|
|
27
|
+
function hmacHex(secret, msg) {
|
|
28
|
+
return createHmac('sha256', secret).update(msg).digest('hex');
|
|
29
|
+
}
|
|
30
|
+
async function getSecret(deps) {
|
|
31
|
+
const opener = deps.vaultOpener ?? (() => Vault.open({ configDir: configDir() }));
|
|
32
|
+
const vault = await opener();
|
|
33
|
+
if (!vault.has(SECRET_SLOT)) {
|
|
34
|
+
throw new Error('HITO 4 client: vault slot "' + SECRET_SLOT + '" is empty. '
|
|
35
|
+
+ 'Run `yf vault set ' + SECRET_SLOT + '` with the value provided '
|
|
36
|
+
+ 'at signup (or your tenant admin).');
|
|
37
|
+
}
|
|
38
|
+
return vault.get(SECRET_SLOT);
|
|
39
|
+
}
|
|
40
|
+
async function getHandle(deps) {
|
|
41
|
+
if (deps.handleProvider)
|
|
42
|
+
return deps.handleProvider();
|
|
43
|
+
const lic = await readLicense();
|
|
44
|
+
if (!lic.user_handle) {
|
|
45
|
+
throw new Error('HITO 4 client: no user_handle on the local license cache. '
|
|
46
|
+
+ 'Run `yf license activate --user-handle <you@example.com>` first.');
|
|
47
|
+
}
|
|
48
|
+
return lic.user_handle;
|
|
49
|
+
}
|
|
50
|
+
export function signBearer(secret, handle, ts = Date.now()) {
|
|
51
|
+
const sig = hmacHex(secret, handle.toLowerCase() + ':' + ts);
|
|
52
|
+
return ts + '.' + sig;
|
|
53
|
+
}
|
|
54
|
+
/** Call a HITO 4 flow. Returns the raw server response (no
|
|
55
|
+
* retry / no backoff -- callers can decide). */
|
|
56
|
+
export async function callFlow(flow, input, deps = {}) {
|
|
57
|
+
const base = deps.baseUrl ?? HITO4_BASE_URL;
|
|
58
|
+
const secret = await getSecret(deps);
|
|
59
|
+
const handle = await getHandle(deps);
|
|
60
|
+
const bearer = signBearer(secret, handle);
|
|
61
|
+
const fetchImpl = deps.fetchImpl ?? ((u, init) => globalThis.fetch(u, init));
|
|
62
|
+
const url = base.replace(/\/+$/, '') + '/v1/flows/' + encodeURIComponent(flow);
|
|
63
|
+
const r = await fetchImpl(url, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
'Authorization': 'Bearer ' + bearer,
|
|
67
|
+
'x-yf-user-handle': handle,
|
|
68
|
+
'content-type': 'application/json',
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify(input ?? null),
|
|
71
|
+
});
|
|
72
|
+
let body = {};
|
|
73
|
+
try {
|
|
74
|
+
body = await r.json();
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
body = {};
|
|
78
|
+
}
|
|
79
|
+
return { ok: r.ok, status: r.status, body };
|
|
80
|
+
}
|
|
81
|
+
/** Pull the up-to-date license row from the server. The CLI's
|
|
82
|
+
* Polar cache is then refreshed with the result. */
|
|
83
|
+
export async function fetchServerLicense(deps = {}) {
|
|
84
|
+
const base = deps.baseUrl ?? HITO4_BASE_URL;
|
|
85
|
+
const secret = await getSecret(deps);
|
|
86
|
+
const handle = await getHandle(deps);
|
|
87
|
+
const bearer = signBearer(secret, handle);
|
|
88
|
+
const fetchImpl = deps.fetchImpl ?? ((u, init) => globalThis.fetch(u, init));
|
|
89
|
+
const url = base.replace(/\/+$/, '') + '/v1/license/' + encodeURIComponent(handle);
|
|
90
|
+
const r = await fetchImpl(url, {
|
|
91
|
+
method: 'GET',
|
|
92
|
+
headers: { 'Authorization': 'Bearer ' + bearer },
|
|
93
|
+
});
|
|
94
|
+
let body = {};
|
|
95
|
+
try {
|
|
96
|
+
body = await r.json();
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
body = {};
|
|
100
|
+
}
|
|
101
|
+
return { ok: r.ok, status: r.status, body };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=hito4_client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hito4_client.js","sourceRoot":"","sources":["../../src/license/hito4_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LicenseState } from './types.js';
|
|
2
|
+
export declare function configDir(): string;
|
|
3
|
+
/**
|
|
4
|
+
* Read (or initialise) the local license state. Idempotent + safe
|
|
5
|
+
* to call on every CLI invocation.
|
|
6
|
+
*
|
|
7
|
+
* Tests inject FORGE_CONFIG_DIR to point at a temp directory; the
|
|
8
|
+
* helper resolves $HOME via os.homedir() so setting HOME in the
|
|
9
|
+
* test process flips the file layout cleanly. Avoids the test
|
|
10
|
+
* harness having to mock fs.
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadLicense(): Promise<LicenseState>;
|
|
13
|
+
export declare function isPaidSeat(state: LicenseState): boolean;
|
|
14
|
+
export declare function isTrialActive(state: LicenseState): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Predicate the CLI uses to gate commercial features. Returns true
|
|
17
|
+
* when the user can use anything Forge offers; false when they're
|
|
18
|
+
* either expired or never had a license (in which case the calling
|
|
19
|
+
* command should print the upgrade nudge).
|
|
20
|
+
*/
|
|
21
|
+
export declare function isAuthorized(state: LicenseState): boolean;
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,YAAY,EAIb,MAAM,YAAY,CAAC;AAIpB,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAoDD;;;;;;;;GAQG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,CAwBzD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEvD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEzD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yujin Forge -- license client.
|
|
3
|
+
*
|
|
4
|
+
* Day-0 implementation handles the TRIAL flow end-to-end (the
|
|
5
|
+
* paid-seat path is stubbed). Trial semantics per docs/SPEC.md
|
|
6
|
+
* section 2.1:
|
|
7
|
+
*
|
|
8
|
+
* - 30 days from first call to loadLicense
|
|
9
|
+
* - cached at ~/.yujin-forge/trial.json
|
|
10
|
+
* - watermarks generated code (handled by callers, not here)
|
|
11
|
+
*
|
|
12
|
+
* The paid-seat path (validate against license.yujin.dev, refresh
|
|
13
|
+
* every 24h, offline grace of 7 days) lands with the License
|
|
14
|
+
* client milestone (docs/SPEC.md section 8).
|
|
15
|
+
*
|
|
16
|
+
* The file layout under ~/.yujin-forge/ is:
|
|
17
|
+
*
|
|
18
|
+
* ~/.yujin-forge/
|
|
19
|
+
* trial.json -- TrialState (set on first invocation)
|
|
20
|
+
* license.json -- SeatToken (set on 'yf license activate')
|
|
21
|
+
*
|
|
22
|
+
* trial.json wins read precedence only if license.json is absent
|
|
23
|
+
* (a paid seat trumps a trial). This is enforced by loadLicense.
|
|
24
|
+
*/
|
|
25
|
+
import { promises as fs } from 'node:fs';
|
|
26
|
+
import { homedir } from 'node:os';
|
|
27
|
+
import path from 'node:path';
|
|
28
|
+
const TRIAL_DAYS = 30;
|
|
29
|
+
export function configDir() {
|
|
30
|
+
return path.join(homedir(), '.yujin-forge');
|
|
31
|
+
}
|
|
32
|
+
function trialPath() { return path.join(configDir(), 'trial.json'); }
|
|
33
|
+
function licensePath() { return path.join(configDir(), 'license.json'); }
|
|
34
|
+
async function readJsonOrNull(file) {
|
|
35
|
+
try {
|
|
36
|
+
const raw = await fs.readFile(file, 'utf-8');
|
|
37
|
+
return JSON.parse(raw);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (err.code === 'ENOENT')
|
|
41
|
+
return null;
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function ensureConfigDir() {
|
|
46
|
+
await fs.mkdir(configDir(), { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
async function readPaidSeat() {
|
|
49
|
+
return readJsonOrNull(licensePath());
|
|
50
|
+
}
|
|
51
|
+
async function readTrial() {
|
|
52
|
+
const stored = await readJsonOrNull(trialPath());
|
|
53
|
+
if (!stored)
|
|
54
|
+
return null;
|
|
55
|
+
return computeTrialState(stored.startedAt, stored.endsAt);
|
|
56
|
+
}
|
|
57
|
+
async function startTrial() {
|
|
58
|
+
await ensureConfigDir();
|
|
59
|
+
const now = new Date();
|
|
60
|
+
const ends = new Date(now.getTime() + TRIAL_DAYS * 24 * 60 * 60 * 1000);
|
|
61
|
+
const stored = {
|
|
62
|
+
startedAt: now.toISOString(),
|
|
63
|
+
endsAt: ends.toISOString(),
|
|
64
|
+
};
|
|
65
|
+
await fs.writeFile(trialPath(), JSON.stringify(stored, null, 2));
|
|
66
|
+
return computeTrialState(stored.startedAt, stored.endsAt);
|
|
67
|
+
}
|
|
68
|
+
function computeTrialState(startedAt, endsAt) {
|
|
69
|
+
const now = Date.now();
|
|
70
|
+
const ends = Date.parse(endsAt);
|
|
71
|
+
const daysLeft = Math.ceil((ends - now) / (24 * 60 * 60 * 1000));
|
|
72
|
+
return { startedAt, endsAt, daysLeft };
|
|
73
|
+
}
|
|
74
|
+
function trialStatus(t) {
|
|
75
|
+
return t.daysLeft > 0 ? 'trial' : 'expired';
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Read (or initialise) the local license state. Idempotent + safe
|
|
79
|
+
* to call on every CLI invocation.
|
|
80
|
+
*
|
|
81
|
+
* Tests inject FORGE_CONFIG_DIR to point at a temp directory; the
|
|
82
|
+
* helper resolves $HOME via os.homedir() so setting HOME in the
|
|
83
|
+
* test process flips the file layout cleanly. Avoids the test
|
|
84
|
+
* harness having to mock fs.
|
|
85
|
+
*/
|
|
86
|
+
export async function loadLicense() {
|
|
87
|
+
const seat = await readPaidSeat();
|
|
88
|
+
if (seat) {
|
|
89
|
+
return {
|
|
90
|
+
status: 'paid',
|
|
91
|
+
source: 'cache:paid',
|
|
92
|
+
seat,
|
|
93
|
+
trial: null,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
let trial = await readTrial();
|
|
97
|
+
let source = 'cache:trial';
|
|
98
|
+
if (!trial) {
|
|
99
|
+
trial = await startTrial();
|
|
100
|
+
source = 'fresh:trial';
|
|
101
|
+
}
|
|
102
|
+
const status = trialStatus(trial);
|
|
103
|
+
return {
|
|
104
|
+
status,
|
|
105
|
+
source: status === 'expired' ? 'absent' : source,
|
|
106
|
+
seat: null,
|
|
107
|
+
trial,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export function isPaidSeat(state) {
|
|
111
|
+
return state.status === 'paid';
|
|
112
|
+
}
|
|
113
|
+
export function isTrialActive(state) {
|
|
114
|
+
return state.status === 'trial';
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Predicate the CLI uses to gate commercial features. Returns true
|
|
118
|
+
* when the user can use anything Forge offers; false when they're
|
|
119
|
+
* either expired or never had a license (in which case the calling
|
|
120
|
+
* command should print the upgrade nudge).
|
|
121
|
+
*/
|
|
122
|
+
export function isAuthorized(state) {
|
|
123
|
+
return isPaidSeat(state) || isTrialActive(state);
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yujin Forge -- license types.
|
|
3
|
+
*
|
|
4
|
+
* The license state is a discriminated union over `status`. The
|
|
5
|
+
* runtime always returns one of these four states; callers check
|
|
6
|
+
* via the helpers in src/license/index.ts (isPaidSeat, etc).
|
|
7
|
+
*/
|
|
8
|
+
export type LicenseStatus = 'paid' | 'trial' | 'expired' | 'absent';
|
|
9
|
+
export type LicenseSource = 'cache:paid' | 'cache:trial' | 'fresh:trial' | 'absent';
|
|
10
|
+
export interface SeatToken {
|
|
11
|
+
/** Opaque server-issued JWT. */
|
|
12
|
+
token: string;
|
|
13
|
+
/** ISO-8601 timestamp for the seat's hard expiry. */
|
|
14
|
+
expiresAt: string | null;
|
|
15
|
+
/** ISO-8601 timestamp the cache was last refreshed against the server. */
|
|
16
|
+
lastCheckedAt: string;
|
|
17
|
+
/** Email the seat is bound to (or null for machine-only seats). */
|
|
18
|
+
email: string | null;
|
|
19
|
+
/** Machine fingerprint the seat is pinned to. */
|
|
20
|
+
machineFingerprint: string;
|
|
21
|
+
}
|
|
22
|
+
export interface TrialState {
|
|
23
|
+
/** ISO-8601 timestamp when the trial was started. */
|
|
24
|
+
startedAt: string;
|
|
25
|
+
/** ISO-8601 timestamp when the trial ends (startedAt + 30 days). */
|
|
26
|
+
endsAt: string;
|
|
27
|
+
/** Convenience -- whole days remaining (negative when expired). */
|
|
28
|
+
daysLeft: number;
|
|
29
|
+
}
|
|
30
|
+
export interface LicenseState {
|
|
31
|
+
status: LicenseStatus;
|
|
32
|
+
source: LicenseSource;
|
|
33
|
+
/** Present when status === 'paid'. */
|
|
34
|
+
seat: SeatToken | null;
|
|
35
|
+
/** Present when status === 'trial' OR 'expired'. */
|
|
36
|
+
trial: TrialState | null;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/license/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEpE,MAAM,MAAM,aAAa,GACrB,YAAY,GACZ,aAAa,GACb,aAAa,GACb,QAAQ,CAAC;AAEb,MAAM,WAAW,SAAS;IACxB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0EAA0E;IAC1E,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iDAAiD;IACjD,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,sCAAsC;IACtC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,oDAAoD;IACpD,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAC1B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yujin Forge -- license types.
|
|
3
|
+
*
|
|
4
|
+
* The license state is a discriminated union over `status`. The
|
|
5
|
+
* runtime always returns one of these four states; callers check
|
|
6
|
+
* via the helpers in src/license/index.ts (isPaidSeat, etc).
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/license/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|