@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,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub-anchored project sync (PLAN #10, soft #5).
|
|
3
|
+
*
|
|
4
|
+
* The user owns a private GitHub repo `yujin-state` whose
|
|
5
|
+
* `projects.json` file is the cross-device truth bus for their
|
|
6
|
+
* Forge project registry. This module:
|
|
7
|
+
*
|
|
8
|
+
* - Bootstraps the repo + file on first sync (creates the
|
|
9
|
+
* repo + commits an empty projects.json).
|
|
10
|
+
* - Pulls the remote file via the GitHub Contents API.
|
|
11
|
+
* - Merges per-slug into the local registry using
|
|
12
|
+
* last-writer-wins on `updated_at`.
|
|
13
|
+
* - Pushes the merged result back.
|
|
14
|
+
*
|
|
15
|
+
* Per-device fields (path, mode-on-this-device) are STRIPPED
|
|
16
|
+
* before push -- only the cross-device fields (slug,
|
|
17
|
+
* github_repo, target, mode-default, last_active_at,
|
|
18
|
+
* updated_at) ride.
|
|
19
|
+
*
|
|
20
|
+
* Auth: vault slot `github_token` with `repo` scope. Same slot
|
|
21
|
+
* used by `yf repo init` + the chat tools.
|
|
22
|
+
*
|
|
23
|
+
* Loud failures: missing vault slot, non-2xx API, optimistic
|
|
24
|
+
* concurrency conflict (412) -> retry once after re-pulling.
|
|
25
|
+
*
|
|
26
|
+
* ASCII-only.
|
|
27
|
+
*/
|
|
28
|
+
import { readRegistry, writeRegistry, } from './projects.js';
|
|
29
|
+
const GITHUB_API = 'https://api.github.com';
|
|
30
|
+
const STATE_REPO = 'yujin-state';
|
|
31
|
+
const STATE_FILE = 'projects.json';
|
|
32
|
+
const STATE_FILE_SCHEMA = 'yujin-state/projects.json/v1';
|
|
33
|
+
/* ------- Strip device-local fields before push ------- */
|
|
34
|
+
export function toRemoteEntry(p) {
|
|
35
|
+
return {
|
|
36
|
+
slug: p.slug,
|
|
37
|
+
...(p.github_repo ? { github_repo: p.github_repo } : {}),
|
|
38
|
+
...(p.target ? { target: p.target } : {}),
|
|
39
|
+
...(p.mode ? { mode: p.mode } : {}),
|
|
40
|
+
...(p.last_active_at ? { last_active_at: p.last_active_at } : {}),
|
|
41
|
+
updated_at: p.updated_at ?? new Date().toISOString(),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Per-slug merge: keep the entry with the higher updated_at.
|
|
45
|
+
* Returns [merged, classifications] -- classifications used
|
|
46
|
+
* by SyncResult. */
|
|
47
|
+
export function mergeRegistries(local, remote) {
|
|
48
|
+
const localBySlug = new Map(local.projects.map((p) => [p.slug, p]));
|
|
49
|
+
const remoteBySlug = new Map(remote.projects.map((p) => [p.slug, p]));
|
|
50
|
+
const allSlugs = new Set([...localBySlug.keys(), ...remoteBySlug.keys()]);
|
|
51
|
+
const pulled_new = [];
|
|
52
|
+
const pulled_updated = [];
|
|
53
|
+
const pushed = [];
|
|
54
|
+
const mergedProjects = [];
|
|
55
|
+
for (const slug of allSlugs) {
|
|
56
|
+
const lo = localBySlug.get(slug);
|
|
57
|
+
const re = remoteBySlug.get(slug);
|
|
58
|
+
if (lo && !re) {
|
|
59
|
+
/* Only local -> push it. */
|
|
60
|
+
mergedProjects.push(lo);
|
|
61
|
+
pushed.push(slug);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (re && !lo) {
|
|
65
|
+
/* Only remote -> pull as remote_only entry. */
|
|
66
|
+
mergedProjects.push({
|
|
67
|
+
slug: re.slug,
|
|
68
|
+
path: '', /* unknown on this device */
|
|
69
|
+
remote_only: true,
|
|
70
|
+
...(re.github_repo ? { github_repo: re.github_repo } : {}),
|
|
71
|
+
...(re.target ? { target: re.target } : {}),
|
|
72
|
+
...(re.mode ? { mode: re.mode } : {}),
|
|
73
|
+
...(re.last_active_at ? { last_active_at: re.last_active_at } : {}),
|
|
74
|
+
updated_at: re.updated_at,
|
|
75
|
+
});
|
|
76
|
+
pulled_new.push(slug);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
/* Both sides have it -- compare timestamps. */
|
|
80
|
+
const loStamp = lo.updated_at ?? '';
|
|
81
|
+
const reStamp = re.updated_at ?? '';
|
|
82
|
+
if (reStamp > loStamp) {
|
|
83
|
+
mergedProjects.push({
|
|
84
|
+
...lo,
|
|
85
|
+
github_repo: re.github_repo ?? lo.github_repo,
|
|
86
|
+
target: re.target ?? lo.target,
|
|
87
|
+
mode: re.mode ?? lo.mode,
|
|
88
|
+
last_active_at: re.last_active_at ?? lo.last_active_at,
|
|
89
|
+
updated_at: re.updated_at,
|
|
90
|
+
});
|
|
91
|
+
pulled_updated.push(slug);
|
|
92
|
+
}
|
|
93
|
+
else if (loStamp > reStamp) {
|
|
94
|
+
mergedProjects.push(lo);
|
|
95
|
+
pushed.push(slug);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
/* Equal -- no change either way. */
|
|
99
|
+
mergedProjects.push(lo);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
merged: { version: 1, active_slug: local.active_slug, projects: mergedProjects },
|
|
104
|
+
pulled_new,
|
|
105
|
+
pulled_updated,
|
|
106
|
+
pushed,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async function getOwnerLogin(token, fetchImpl) {
|
|
110
|
+
const r = await fetchImpl(GITHUB_API + '/user', {
|
|
111
|
+
headers: {
|
|
112
|
+
Authorization: 'Bearer ' + token,
|
|
113
|
+
Accept: 'application/vnd.github+json',
|
|
114
|
+
'User-Agent': 'yujin-forge',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
if (!r.ok)
|
|
118
|
+
throw new Error('GitHub GET /user ' + r.status);
|
|
119
|
+
const j = await r.json();
|
|
120
|
+
return j.login;
|
|
121
|
+
}
|
|
122
|
+
async function createStateRepo(token, name, fetchImpl) {
|
|
123
|
+
const r = await fetchImpl(GITHUB_API + '/user/repos', {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
headers: {
|
|
126
|
+
Authorization: 'Bearer ' + token,
|
|
127
|
+
Accept: 'application/vnd.github+json',
|
|
128
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
129
|
+
'Content-Type': 'application/json',
|
|
130
|
+
'User-Agent': 'yujin-forge',
|
|
131
|
+
},
|
|
132
|
+
body: JSON.stringify({
|
|
133
|
+
name,
|
|
134
|
+
private: true,
|
|
135
|
+
auto_init: true,
|
|
136
|
+
description: 'Yujin Forge cross-device project state (managed by yf).',
|
|
137
|
+
}),
|
|
138
|
+
});
|
|
139
|
+
if (!r.ok) {
|
|
140
|
+
let body = '';
|
|
141
|
+
try {
|
|
142
|
+
body = await r.text();
|
|
143
|
+
}
|
|
144
|
+
catch { /* */ }
|
|
145
|
+
throw new Error('GitHub POST /user/repos ' + r.status + ': ' + body.slice(0, 300));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function readRemoteState(token, owner, repoName, fetchImpl) {
|
|
149
|
+
const url = GITHUB_API + '/repos/' + owner + '/' + repoName + '/contents/' + STATE_FILE;
|
|
150
|
+
const r = await fetchImpl(url, {
|
|
151
|
+
headers: {
|
|
152
|
+
Authorization: 'Bearer ' + token,
|
|
153
|
+
Accept: 'application/vnd.github+json',
|
|
154
|
+
'User-Agent': 'yujin-forge',
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
if (r.status === 404) {
|
|
158
|
+
/* Distinguish "file missing inside existing repo" from
|
|
159
|
+
* "repo missing entirely" by probing the repo itself. */
|
|
160
|
+
const repoR = await fetchImpl(GITHUB_API + '/repos/' + owner + '/' + repoName, {
|
|
161
|
+
headers: {
|
|
162
|
+
Authorization: 'Bearer ' + token,
|
|
163
|
+
Accept: 'application/vnd.github+json',
|
|
164
|
+
'User-Agent': 'yujin-forge',
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
if (repoR.status === 404)
|
|
168
|
+
return { state: null, sha: null, repoMissing: true };
|
|
169
|
+
return { state: null, sha: null, repoMissing: false };
|
|
170
|
+
}
|
|
171
|
+
if (!r.ok)
|
|
172
|
+
throw new Error('GitHub GET contents ' + r.status);
|
|
173
|
+
const j = await r.json();
|
|
174
|
+
if (!j.content || j.encoding !== 'base64')
|
|
175
|
+
throw new Error('unexpected contents response shape');
|
|
176
|
+
const text = Buffer.from(j.content, 'base64').toString('utf8');
|
|
177
|
+
let parsed;
|
|
178
|
+
try {
|
|
179
|
+
parsed = JSON.parse(text);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
/* Treat a malformed remote file as empty state -- we will
|
|
183
|
+
* overwrite it. */
|
|
184
|
+
return { state: { version: 1, schema: STATE_FILE_SCHEMA, projects: [] }, sha: j.sha ?? null, repoMissing: false };
|
|
185
|
+
}
|
|
186
|
+
return { state: parsed, sha: j.sha ?? null, repoMissing: false };
|
|
187
|
+
}
|
|
188
|
+
async function writeRemoteState(token, owner, repoName, state, sha, fetchImpl) {
|
|
189
|
+
const url = GITHUB_API + '/repos/' + owner + '/' + repoName + '/contents/' + STATE_FILE;
|
|
190
|
+
const content = Buffer.from(JSON.stringify(state, null, 2) + '\n', 'utf8').toString('base64');
|
|
191
|
+
const body = {
|
|
192
|
+
message: 'yf sync ' + new Date().toISOString(),
|
|
193
|
+
content,
|
|
194
|
+
};
|
|
195
|
+
if (sha)
|
|
196
|
+
body.sha = sha;
|
|
197
|
+
const r = await fetchImpl(url, {
|
|
198
|
+
method: 'PUT',
|
|
199
|
+
headers: {
|
|
200
|
+
Authorization: 'Bearer ' + token,
|
|
201
|
+
Accept: 'application/vnd.github+json',
|
|
202
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
203
|
+
'Content-Type': 'application/json',
|
|
204
|
+
'User-Agent': 'yujin-forge',
|
|
205
|
+
},
|
|
206
|
+
body: JSON.stringify(body),
|
|
207
|
+
});
|
|
208
|
+
if (!r.ok) {
|
|
209
|
+
let detail = '';
|
|
210
|
+
try {
|
|
211
|
+
detail = await r.text();
|
|
212
|
+
}
|
|
213
|
+
catch { /* */ }
|
|
214
|
+
throw new Error('GitHub PUT contents ' + r.status + ': ' + detail.slice(0, 300));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Run a full bidirectional sync. Caller orchestrates retries. */
|
|
218
|
+
export async function syncProjects(opts = {}, deps) {
|
|
219
|
+
const fetchImpl = deps.fetchImpl ?? ((u, init) => globalThis.fetch(u, init));
|
|
220
|
+
const repoName = deps.stateRepoName ?? STATE_REPO;
|
|
221
|
+
const token = await deps.tokenProvider();
|
|
222
|
+
const owner = deps.ownerProvider ? await deps.ownerProvider() : await getOwnerLogin(token, fetchImpl);
|
|
223
|
+
/* 1. Read remote (bootstrap repo if missing). */
|
|
224
|
+
let remoteResult = await readRemoteState(token, owner, repoName, fetchImpl);
|
|
225
|
+
let bootstrapped = false;
|
|
226
|
+
if (remoteResult.repoMissing) {
|
|
227
|
+
await createStateRepo(token, repoName, fetchImpl);
|
|
228
|
+
bootstrapped = true;
|
|
229
|
+
/* After auto_init the repo has no projects.json yet. */
|
|
230
|
+
remoteResult = { state: null, sha: null, repoMissing: false };
|
|
231
|
+
}
|
|
232
|
+
const remoteState = remoteResult.state
|
|
233
|
+
?? { version: 1, schema: STATE_FILE_SCHEMA, projects: [] };
|
|
234
|
+
/* 2. Merge. */
|
|
235
|
+
const local = await readRegistry();
|
|
236
|
+
const { merged, pulled_new, pulled_updated, pushed } = mergeRegistries(local, remoteState);
|
|
237
|
+
/* 3. Write local (unless pushOnly). */
|
|
238
|
+
if (!opts.pushOnly)
|
|
239
|
+
await writeRegistry(merged);
|
|
240
|
+
/* 4. Write remote (unless pullOnly). */
|
|
241
|
+
if (!opts.pullOnly) {
|
|
242
|
+
const nextRemote = {
|
|
243
|
+
version: 1, schema: STATE_FILE_SCHEMA,
|
|
244
|
+
projects: merged.projects.map(toRemoteEntry),
|
|
245
|
+
};
|
|
246
|
+
try {
|
|
247
|
+
await writeRemoteState(token, owner, repoName, nextRemote, remoteResult.sha, fetchImpl);
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
251
|
+
if (/\b409\b|\b412\b|sha was/i.test(msg)) {
|
|
252
|
+
/* Concurrent write -- re-pull + retry once. */
|
|
253
|
+
const fresh = await readRemoteState(token, owner, repoName, fetchImpl);
|
|
254
|
+
const freshState = fresh.state ?? { version: 1, schema: STATE_FILE_SCHEMA, projects: [] };
|
|
255
|
+
const m2 = mergeRegistries(merged, freshState).merged;
|
|
256
|
+
if (!opts.pushOnly)
|
|
257
|
+
await writeRegistry(m2);
|
|
258
|
+
const retryRemote = {
|
|
259
|
+
version: 1, schema: STATE_FILE_SCHEMA,
|
|
260
|
+
projects: m2.projects.map(toRemoteEntry),
|
|
261
|
+
};
|
|
262
|
+
await writeRemoteState(token, owner, repoName, retryRemote, fresh.sha, fetchImpl);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
throw err;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
ok: true,
|
|
271
|
+
remote_repo: owner + '/' + repoName,
|
|
272
|
+
pulled_new,
|
|
273
|
+
pulled_updated,
|
|
274
|
+
pushed,
|
|
275
|
+
bootstrapped,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=projects_sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects_sync.js","sourceRoot":"","sources":["../../src/core/projects_sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EACL,YAAY,EAAE,aAAa,GAC5B,MAAM,eAAe,CAAC;AAEvB,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAC5C,MAAM,UAAU,GAAG,aAAa,CAAC;AACjC,MAAM,UAAU,GAAG,eAAe,CAAC;AACnC,MAAM,iBAAiB,GAAG,8BAA8B,CAAC;AAwCzD,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,CAAe;IAC3C,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrD,CAAC;AACJ,CAAC;AAED;;qBAEqB;AACrB,MAAM,UAAU,eAAe,CAC7B,KAAuB,EACvB,MAAuB;IAOvB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAE1E,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,MAAM,cAAc,GAAmB,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YACd,4BAA4B;YAC5B,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YACd,+CAA+C;YAC/C,cAAc,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,IAAI,EAAE,EAAE,EAAiC,4BAA4B;gBACrE,WAAW,EAAE,IAAI;gBACjB,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1D,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3C,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrC,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnE,UAAU,EAAE,EAAE,CAAC,UAAU;aAC1B,CAAC,CAAC;YACH,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QACD,+CAA+C;QAC/C,MAAM,OAAO,GAAG,EAAG,CAAC,UAAU,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,EAAG,CAAC,UAAU,IAAI,EAAE,CAAC;QACrC,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;YACtB,cAAc,CAAC,IAAI,CAAC;gBAClB,GAAG,EAAG;gBACN,WAAW,EAAE,EAAG,CAAC,WAAW,IAAI,EAAG,CAAC,WAAW;gBAC/C,MAAM,EAAE,EAAG,CAAC,MAAM,IAAI,EAAG,CAAC,MAAM;gBAChC,IAAI,EAAE,EAAG,CAAC,IAAI,IAAI,EAAG,CAAC,IAAI;gBAC1B,cAAc,EAAE,EAAG,CAAC,cAAc,IAAI,EAAG,CAAC,cAAc;gBACxD,UAAU,EAAE,EAAG,CAAC,UAAU;aAC3B,CAAC,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;YAC7B,cAAc,CAAC,IAAI,CAAC,EAAG,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,oCAAoC;YACpC,cAAc,CAAC,IAAI,CAAC,EAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE;QAChF,UAAU;QACV,cAAc;QACd,MAAM;KACP,CAAC;AACJ,CAAC;AAaD,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,SAAuB;IACjE,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,UAAU,GAAG,OAAO,EAAE;QAC9C,OAAO,EAAE;YACP,aAAa,EAAE,SAAS,GAAG,KAAK;YAChC,MAAM,EAAE,6BAA6B;YACrC,YAAY,EAAE,aAAa;SAC5B;KACF,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC3D,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAiB,CAAC;IACxC,OAAO,CAAC,CAAC,KAAK,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,KAAa,EAAE,IAAY,EAAE,SAAuB;IAEpD,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,UAAU,GAAG,aAAa,EAAE;QACpD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,SAAS,GAAG,KAAK;YAChC,MAAM,EAAE,6BAA6B;YACrC,sBAAsB,EAAE,YAAY;YACpC,cAAc,EAAE,kBAAkB;YAClC,YAAY,EAAE,aAAa;SAC5B;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,IAAI;YACJ,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,yDAAyD;SACvE,CAAC;KACH,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACV,IAAI,IAAI,GAAG,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,KAAa,EAAE,KAAa,EAAE,QAAgB,EAAE,SAAuB;IAEvE,MAAM,GAAG,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,GAAG,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;IACxF,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;QAC7B,OAAO,EAAE;YACP,aAAa,EAAE,SAAS,GAAG,KAAK;YAChC,MAAM,EAAE,6BAA6B;YACrC,YAAY,EAAE,aAAa;SAC5B;KACF,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACrB;iEACyD;QACzD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,GAAG,GAAG,QAAQ,EAAE;YAC7E,OAAO,EAAE;gBACP,aAAa,EAAE,SAAS,GAAG,KAAK;gBAChC,MAAM,EAAE,6BAA6B;gBACrC,YAAY,EAAE,aAAa;aAC5B;SACF,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC/E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAoB,CAAC;IAC3C,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACjG,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/D,IAAI,MAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAoB,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP;2BACmB;QACnB,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACpH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AACnE,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,KAAa,EAAE,KAAa,EAAE,QAAgB,EAC9C,KAAsB,EAAE,GAAkB,EAAE,SAAuB;IAEnE,MAAM,GAAG,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,GAAG,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;IACxF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC9F,MAAM,IAAI,GAA4B;QACpC,OAAO,EAAE,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC9C,OAAO;KACR,CAAC;IACF,IAAI,GAAG;QAAE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACxB,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;QAC7B,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,aAAa,EAAE,SAAS,GAAG,KAAK;YAChC,MAAM,EAAE,6BAA6B;YACrC,sBAAsB,EAAE,YAAY;YACpC,cAAc,EAAE,kBAAkB;YAClC,YAAY,EAAE,aAAa;SAC5B;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACV,IAAI,MAAM,GAAG,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAmD,EAAE,EACrD,IAAc;IAEd,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAM,EAAE,IAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACxF,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,IAAI,UAAU,CAAC;IAClD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAEtG,iDAAiD;IACjD,IAAI,YAAY,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5E,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAClD,YAAY,GAAG,IAAI,CAAC;QACpB,wDAAwD;QACxD,YAAY,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAChE,CAAC;IACD,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK;WACjC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE7D,eAAe;IACf,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAE3F,uCAAuC;IACvC,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;IAEhD,wCAAwC;IACxC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,UAAU,GAAoB;YAClC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB;YACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC;SAC7C,CAAC;QACF,IAAI,CAAC;YACH,MAAM,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,IAAI,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzC,+CAA+C;gBAC/C,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;gBACvE,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;gBAC1F,MAAM,EAAE,GAAG,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC;gBACtD,IAAI,CAAC,IAAI,CAAC,QAAQ;oBAAE,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;gBAC5C,MAAM,WAAW,GAAoB;oBACnC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB;oBACrC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC;iBACzC,CAAC;gBACF,MAAM,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YACpF,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,WAAW,EAAE,KAAK,GAAG,GAAG,GAAG,QAAQ;QACnC,UAAU;QACV,cAAc;QACd,MAAM;QACN,YAAY;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote runner -- bridges the cascade router's RouteDecision
|
|
3
|
+
* to an actual `yf <command>` execution against the chosen
|
|
4
|
+
* target.
|
|
5
|
+
*
|
|
6
|
+
* Three execution shapes:
|
|
7
|
+
*
|
|
8
|
+
* laptop_lan -> HTTP POST to <endpoint>/v1/exec with
|
|
9
|
+
* { command, args }; expect a JSON response.
|
|
10
|
+
* cf_tunnel -> same HTTP shape, just a different URL.
|
|
11
|
+
* github_actions -> dispatchWorkflow + poll fetchRunResult
|
|
12
|
+
* until done.
|
|
13
|
+
*
|
|
14
|
+
* The runner does NOT itself probe -- decideRoute (from
|
|
15
|
+
* cascade_router) has already done that. The runner is a thin
|
|
16
|
+
* executor with timeout, error normalisation, and a uniform
|
|
17
|
+
* { ok, exit, stdout, stderr, target, durationMs } shape so
|
|
18
|
+
* the chat UI can render the result without target-specific
|
|
19
|
+
* branching.
|
|
20
|
+
*
|
|
21
|
+
* ASCII-only.
|
|
22
|
+
*/
|
|
23
|
+
import { type ComputeClass, type CascadeEndpoints, type CascadeProbes, type RouteDecision } from './cascade_router.js';
|
|
24
|
+
import { type DispatchResult } from './gha_dispatcher.js';
|
|
25
|
+
export interface RunCommandResult {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
exit: number;
|
|
28
|
+
stdout: string;
|
|
29
|
+
stderr: string;
|
|
30
|
+
/** Which target ran the command (or null when nothing was
|
|
31
|
+
* reachable). */
|
|
32
|
+
target: RouteDecision['target'];
|
|
33
|
+
durationMs: number;
|
|
34
|
+
/** When ok=false, populated. */
|
|
35
|
+
error?: string;
|
|
36
|
+
/** Full RouteDecision audit -- helps debug "why this target?". */
|
|
37
|
+
route: RouteDecision;
|
|
38
|
+
}
|
|
39
|
+
export interface RunCommandInput {
|
|
40
|
+
command: string;
|
|
41
|
+
args?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface RunCommandDeps {
|
|
44
|
+
fetchImpl?: typeof fetch;
|
|
45
|
+
/** GitHub PAT for the Actions fallback. */
|
|
46
|
+
githubToken?: string;
|
|
47
|
+
/** Override the GHA dispatch -- tests inject a stub. */
|
|
48
|
+
dispatchWorkflowImpl?: (repo: string, command: string, args: string, token: string) => Promise<DispatchResult>;
|
|
49
|
+
/** Override the GHA poll. Returns the final RunStatus + content
|
|
50
|
+
* when ready, null while still pending. */
|
|
51
|
+
fetchRunResultImpl?: (repo: string, runId: string, token: string) => Promise<{
|
|
52
|
+
status: string;
|
|
53
|
+
stdout?: string;
|
|
54
|
+
stderr?: string;
|
|
55
|
+
exit?: number;
|
|
56
|
+
duration_seconds?: number;
|
|
57
|
+
} | null>;
|
|
58
|
+
/** Poll cadence + timeout for the GHA path. */
|
|
59
|
+
pollIntervalMs?: number;
|
|
60
|
+
ghaTimeoutMs?: number;
|
|
61
|
+
/** Per-HTTP-call timeout (laptop_lan + cf_tunnel). */
|
|
62
|
+
httpTimeoutMs?: number;
|
|
63
|
+
/** Clock injector for tests. */
|
|
64
|
+
now?: () => number;
|
|
65
|
+
/** Sleep injector for tests. */
|
|
66
|
+
sleep?: (ms: number) => Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
/** Run a `yf <command> [args]` against the routed target. */
|
|
69
|
+
export declare function runRemoteCommand(cmd: RunCommandInput, computeClass: ComputeClass, endpoints: CascadeEndpoints, probes: CascadeProbes, deps?: RunCommandDeps): Promise<RunCommandResult>;
|
|
70
|
+
//# sourceMappingURL=remote_runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote_runner.d.ts","sourceRoot":"","sources":["../../src/core/remote_runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAe,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpI,OAAO,EAAoC,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE5F,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf;sBACkB;IAClB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,oBAAoB,CAAC,EAAE,CACrB,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KACvD,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B;gDAC4C;IAC5C,kBAAkB,CAAC,EAAE,CACnB,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KACvC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACpH,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,gCAAgC;IAChC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AA8ED,6DAA6D;AAC7D,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,eAAe,EACpB,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,gBAAgB,EAC3B,MAAM,EAAE,aAAa,EACrB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAmC3B"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote runner -- bridges the cascade router's RouteDecision
|
|
3
|
+
* to an actual `yf <command>` execution against the chosen
|
|
4
|
+
* target.
|
|
5
|
+
*
|
|
6
|
+
* Three execution shapes:
|
|
7
|
+
*
|
|
8
|
+
* laptop_lan -> HTTP POST to <endpoint>/v1/exec with
|
|
9
|
+
* { command, args }; expect a JSON response.
|
|
10
|
+
* cf_tunnel -> same HTTP shape, just a different URL.
|
|
11
|
+
* github_actions -> dispatchWorkflow + poll fetchRunResult
|
|
12
|
+
* until done.
|
|
13
|
+
*
|
|
14
|
+
* The runner does NOT itself probe -- decideRoute (from
|
|
15
|
+
* cascade_router) has already done that. The runner is a thin
|
|
16
|
+
* executor with timeout, error normalisation, and a uniform
|
|
17
|
+
* { ok, exit, stdout, stderr, target, durationMs } shape so
|
|
18
|
+
* the chat UI can render the result without target-specific
|
|
19
|
+
* branching.
|
|
20
|
+
*
|
|
21
|
+
* ASCII-only.
|
|
22
|
+
*/
|
|
23
|
+
import { decideRoute } from './cascade_router.js';
|
|
24
|
+
import { dispatchWorkflow, fetchRunResult } from './gha_dispatcher.js';
|
|
25
|
+
function defaultSleep(ms) {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
const t = setTimeout(resolve, ms);
|
|
28
|
+
if (typeof t.unref === 'function') {
|
|
29
|
+
t.unref();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async function httpExec(endpoint, cmd, deps) {
|
|
34
|
+
const fetchImpl = deps.fetchImpl ?? ((u, init) => globalThis.fetch(u, init));
|
|
35
|
+
const url = endpoint.replace(/\/+$/, '') + '/v1/exec';
|
|
36
|
+
const ctrl = new AbortController();
|
|
37
|
+
const timer = setTimeout(() => ctrl.abort(), deps.httpTimeoutMs ?? 60_000);
|
|
38
|
+
try {
|
|
39
|
+
const r = await fetchImpl(url, {
|
|
40
|
+
method: 'POST',
|
|
41
|
+
headers: { 'content-type': 'application/json' },
|
|
42
|
+
body: JSON.stringify({ command: cmd.command, args: cmd.args ?? '' }),
|
|
43
|
+
signal: ctrl.signal,
|
|
44
|
+
});
|
|
45
|
+
if (!r.ok) {
|
|
46
|
+
let detail = '';
|
|
47
|
+
try {
|
|
48
|
+
detail = await r.text();
|
|
49
|
+
}
|
|
50
|
+
catch { /* */ }
|
|
51
|
+
return { exit: 1, stdout: '', stderr: 'HTTP ' + r.status + ': ' + detail.slice(0, 400) };
|
|
52
|
+
}
|
|
53
|
+
const body = await r.json();
|
|
54
|
+
return {
|
|
55
|
+
exit: typeof body.exit === 'number' ? body.exit : 0,
|
|
56
|
+
stdout: typeof body.stdout === 'string' ? body.stdout : '',
|
|
57
|
+
stderr: typeof body.stderr === 'string' ? body.stderr : '',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
clearTimeout(timer);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function ghaExec(repo, cmd, deps) {
|
|
65
|
+
if (!deps.githubToken) {
|
|
66
|
+
return { exit: 1, stdout: '', stderr: 'github_actions target requested but no githubToken provided' };
|
|
67
|
+
}
|
|
68
|
+
const dispatch = deps.dispatchWorkflowImpl ?? dispatchWorkflow;
|
|
69
|
+
const poll = deps.fetchRunResultImpl ?? fetchRunResult;
|
|
70
|
+
const sleep = deps.sleep ?? defaultSleep;
|
|
71
|
+
const now = deps.now ?? Date.now;
|
|
72
|
+
const interval = deps.pollIntervalMs ?? 5_000;
|
|
73
|
+
const timeout = deps.ghaTimeoutMs ?? 30 * 60 * 1000;
|
|
74
|
+
const disp = await dispatch(repo, cmd.command, cmd.args ?? '', deps.githubToken);
|
|
75
|
+
if (!disp.ok || !disp.run_id) {
|
|
76
|
+
return { exit: 1, stdout: '', stderr: 'dispatch failed: ' + (disp.error ?? 'unknown') };
|
|
77
|
+
}
|
|
78
|
+
const startedAt = now();
|
|
79
|
+
while (now() - startedAt < timeout) {
|
|
80
|
+
const result = await poll(repo, disp.run_id, deps.githubToken);
|
|
81
|
+
if (result) {
|
|
82
|
+
const exit = typeof result.exit === 'number' ? result.exit : (result.status === 'success' ? 0 : 1);
|
|
83
|
+
return {
|
|
84
|
+
exit,
|
|
85
|
+
stdout: result.stdout ?? '',
|
|
86
|
+
stderr: result.stderr ?? '',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
await sleep(interval);
|
|
90
|
+
}
|
|
91
|
+
return { exit: 1, stdout: '', stderr: 'github_actions timed out after ' + timeout + 'ms' };
|
|
92
|
+
}
|
|
93
|
+
/** Run a `yf <command> [args]` against the routed target. */
|
|
94
|
+
export async function runRemoteCommand(cmd, computeClass, endpoints, probes, deps = {}) {
|
|
95
|
+
const t0 = (deps.now ?? Date.now)();
|
|
96
|
+
const route = await decideRoute(computeClass, endpoints, probes, {});
|
|
97
|
+
if (!route.target) {
|
|
98
|
+
return {
|
|
99
|
+
ok: false, exit: 1, stdout: '', stderr: route.reason,
|
|
100
|
+
target: null, durationMs: (deps.now ?? Date.now)() - t0,
|
|
101
|
+
error: route.reason, route,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
let payload;
|
|
106
|
+
if (route.target === 'laptop_lan' || route.target === 'cf_tunnel') {
|
|
107
|
+
if (!route.endpoint)
|
|
108
|
+
throw new Error(route.target + ' picked but endpoint missing');
|
|
109
|
+
payload = await httpExec(route.endpoint, cmd, deps);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
/* github_actions */
|
|
113
|
+
if (!route.endpoint)
|
|
114
|
+
throw new Error('github_actions picked but no repo configured');
|
|
115
|
+
payload = await ghaExec(route.endpoint, cmd, deps);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
ok: payload.exit === 0,
|
|
119
|
+
exit: payload.exit, stdout: payload.stdout, stderr: payload.stderr,
|
|
120
|
+
target: route.target, durationMs: (deps.now ?? Date.now)() - t0,
|
|
121
|
+
route,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
return {
|
|
126
|
+
ok: false, exit: 1, stdout: '', stderr: err instanceof Error ? err.message : String(err),
|
|
127
|
+
target: route.target, durationMs: (deps.now ?? Date.now)() - t0,
|
|
128
|
+
error: err instanceof Error ? err.message : String(err),
|
|
129
|
+
route,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=remote_runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote_runner.js","sourceRoot":"","sources":["../../src/core/remote_runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface RepoState {
|
|
2
|
+
/** Absolute directory we probed. */
|
|
3
|
+
path: string;
|
|
4
|
+
/** True if `.git/` exists as a directory or worktree pointer file. */
|
|
5
|
+
is_git: boolean;
|
|
6
|
+
/** Remote URLs (origin first, then alphabetical). Empty when
|
|
7
|
+
* no remotes are configured. */
|
|
8
|
+
remotes: string[];
|
|
9
|
+
/** Convenience flag: at least one remote whose host is github.com. */
|
|
10
|
+
has_github_remote: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** True when the directory or one of its ancestors contains a
|
|
13
|
+
* `.git/` entry. Mirrors `git rev-parse --is-inside-work-tree`
|
|
14
|
+
* without spawning git -- safer + faster on a hot path. */
|
|
15
|
+
export declare function isGitRepo(dir: string): Promise<boolean>;
|
|
16
|
+
/** Read remotes from `git remote -v`. Empty array when the dir
|
|
17
|
+
* isn't a repo or git is missing. */
|
|
18
|
+
export declare function listRemotes(dir: string): Promise<string[]>;
|
|
19
|
+
export declare function inspectRepoState(dir: string): Promise<RepoState>;
|
|
20
|
+
/** Single-line stdout-friendly warning summary for chat /
|
|
21
|
+
* projects callers. Empty string when the dir IS a repo with
|
|
22
|
+
* any remote -- callers print nothing in that case. */
|
|
23
|
+
export declare function formatRepoStateWarning(state: RepoState): string;
|
|
24
|
+
//# sourceMappingURL=repo_state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo_state.d.ts","sourceRoot":"","sources":["../../src/core/repo_state.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,SAAS;IACxB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;IAChB;qCACiC;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sEAAsE;IACtE,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;4DAE4D;AAC5D,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAmB7D;AAED;sCACsC;AACtC,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BhE;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAMtE;AAED;;wDAEwD;AACxD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAS/D"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo-state inspection for the "trabajar sin repo" warning.
|
|
3
|
+
*
|
|
4
|
+
* Forge prefers projects to live in a git repo (any remote --
|
|
5
|
+
* GitHub, GitLab, Bitbucket, local-only). When the user starts
|
|
6
|
+
* Forge against a plain directory we still let them work, but
|
|
7
|
+
* we surface a one-time warning explaining the trade-offs:
|
|
8
|
+
*
|
|
9
|
+
* - No cross-device sync (yujin-state can't follow you).
|
|
10
|
+
* - No automatic Forge backup.
|
|
11
|
+
* - No `yf license cancel`-style audit trail.
|
|
12
|
+
*
|
|
13
|
+
* Pablo 2026-05-26: "permite trabajar sin repo, solo local,
|
|
14
|
+
* con advertencia."
|
|
15
|
+
*
|
|
16
|
+
* This module is pure I/O on `.git/` and `git remote -v`; it
|
|
17
|
+
* never mutates state, never executes git for write paths.
|
|
18
|
+
*
|
|
19
|
+
* ASCII-only.
|
|
20
|
+
*/
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { promises as fs } from 'node:fs';
|
|
23
|
+
import { spawn } from 'node:child_process';
|
|
24
|
+
/** True when the directory or one of its ancestors contains a
|
|
25
|
+
* `.git/` entry. Mirrors `git rev-parse --is-inside-work-tree`
|
|
26
|
+
* without spawning git -- safer + faster on a hot path. */
|
|
27
|
+
export async function isGitRepo(dir) {
|
|
28
|
+
let cur = path.resolve(dir);
|
|
29
|
+
const root = path.parse(cur).root;
|
|
30
|
+
while (true) {
|
|
31
|
+
const candidate = path.join(cur, '.git');
|
|
32
|
+
try {
|
|
33
|
+
const st = await fs.stat(candidate);
|
|
34
|
+
if (st.isDirectory())
|
|
35
|
+
return true;
|
|
36
|
+
/* Worktrees + submodules use a file with `gitdir: ` prefix. */
|
|
37
|
+
if (st.isFile()) {
|
|
38
|
+
const buf = await fs.readFile(candidate, 'utf8');
|
|
39
|
+
if (buf.startsWith('gitdir:'))
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch { /* not present at this level */ }
|
|
44
|
+
if (cur === root)
|
|
45
|
+
return false;
|
|
46
|
+
const next = path.dirname(cur);
|
|
47
|
+
if (next === cur)
|
|
48
|
+
return false;
|
|
49
|
+
cur = next;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Read remotes from `git remote -v`. Empty array when the dir
|
|
53
|
+
* isn't a repo or git is missing. */
|
|
54
|
+
export async function listRemotes(dir) {
|
|
55
|
+
if (!(await isGitRepo(dir)))
|
|
56
|
+
return [];
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
const proc = spawn('git', ['-C', dir, 'remote', '-v'], {
|
|
59
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
60
|
+
});
|
|
61
|
+
let stdout = '';
|
|
62
|
+
proc.stdout.on('data', (b) => { stdout += b.toString('utf-8'); });
|
|
63
|
+
proc.on('error', () => resolve([]));
|
|
64
|
+
proc.on('close', () => {
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const line of stdout.split('\n')) {
|
|
68
|
+
const m = line.match(/^\S+\s+(\S+)\s+\(fetch\)/);
|
|
69
|
+
if (m && m[1] && !seen.has(m[1])) {
|
|
70
|
+
seen.add(m[1]);
|
|
71
|
+
out.push(m[1]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/* origin first when present, rest alphabetical. */
|
|
75
|
+
const origin = out.find((u) => /\/origin(\.git)?$/.test(u));
|
|
76
|
+
const sorted = out.sort();
|
|
77
|
+
if (origin) {
|
|
78
|
+
const idx = sorted.indexOf(origin);
|
|
79
|
+
if (idx > 0) {
|
|
80
|
+
sorted.splice(idx, 1);
|
|
81
|
+
sorted.unshift(origin);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
resolve(sorted);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
export async function inspectRepoState(dir) {
|
|
89
|
+
const abs = path.resolve(dir);
|
|
90
|
+
const is_git = await isGitRepo(abs);
|
|
91
|
+
const remotes = is_git ? await listRemotes(abs) : [];
|
|
92
|
+
const has_github_remote = remotes.some((u) => /github\.com[/:]/.test(u));
|
|
93
|
+
return { path: abs, is_git, remotes, has_github_remote };
|
|
94
|
+
}
|
|
95
|
+
/** Single-line stdout-friendly warning summary for chat /
|
|
96
|
+
* projects callers. Empty string when the dir IS a repo with
|
|
97
|
+
* any remote -- callers print nothing in that case. */
|
|
98
|
+
export function formatRepoStateWarning(state) {
|
|
99
|
+
if (state.is_git && state.remotes.length > 0)
|
|
100
|
+
return '';
|
|
101
|
+
if (state.is_git && state.remotes.length === 0) {
|
|
102
|
+
return 'WARNING: git repo with no remote -- cross-device sync + Forge backup are OFF. '
|
|
103
|
+
+ 'Run `yf repo init --remote` (or push to a hosted remote manually) to enable them.';
|
|
104
|
+
}
|
|
105
|
+
return 'WARNING: ' + state.path + ' is NOT a git repo. '
|
|
106
|
+
+ 'You can still work locally, but cross-device sync + Forge backup are OFF. '
|
|
107
|
+
+ 'Run `yf repo init` to convert this folder into a git repo (optionally with a GitHub remote).';
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=repo_state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo_state.js","sourceRoot":"","sources":["../../src/core/repo_state.ts"],"names":[],"mappings":"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"}
|