@skaile/workspaces 6.3.0 → 6.5.0
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/CHANGELOG.md +72 -1
- package/README.md +4 -0
- package/dist/ai-sdk.js +74 -32
- package/dist/ai-sdk.js.map +1 -1
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-3YO2352Y.js → asset-feeds-4I6Z4OI3.js} +21 -21
- package/dist/{asset-feeds-3YO2352Y.js.map → asset-feeds-4I6Z4OI3.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.js +7 -7
- package/dist/asset-manager/index.js +13 -13
- package/dist/asset-manager/installer.js +9 -9
- package/dist/asset-manager/renderers.js +8 -8
- package/dist/asset-manager/src/index.d.ts +156 -27
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/install-instances.d.ts +2 -0
- package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +6 -0
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/bridge/harnesses/claude-sdk.js +23 -18
- package/dist/bridge/harnesses/claude-sdk.js.map +1 -1
- package/dist/bridge/harnesses/codex.js +36 -34
- package/dist/bridge/harnesses/codex.js.map +1 -1
- package/dist/bridge/harnesses/continue.js +11 -12
- package/dist/bridge/harnesses/continue.js.map +1 -1
- package/dist/bridge/harnesses/echo.js +4 -5
- package/dist/bridge/harnesses/echo.js.map +1 -1
- package/dist/bridge/harnesses/gemini.js +8 -9
- package/dist/bridge/harnesses/goose.js +11 -12
- package/dist/bridge/harnesses/goose.js.map +1 -1
- package/dist/bridge/harnesses/omp.js +16 -11
- package/dist/bridge/harnesses/omp.js.map +1 -1
- package/dist/bridge/harnesses/opencode.js +11 -12
- package/dist/bridge/harnesses/opencode.js.map +1 -1
- package/dist/bridge/harnesses/qwen.js +8 -9
- package/dist/bridge/harnesses/qwen.js.map +1 -1
- package/dist/bridge/index.js +19 -20
- package/dist/bridge/src/ai-sdk.d.ts +5 -2
- package/dist/bridge/src/ai-sdk.d.ts.map +1 -1
- package/dist/bridge/src/codex/login-fallback.d.ts +39 -0
- package/dist/bridge/src/codex/login-fallback.d.ts.map +1 -0
- package/dist/bridge/src/error-classifier.d.ts +6 -0
- package/dist/bridge/src/error-classifier.d.ts.map +1 -1
- package/dist/bridge/src/harness-model-check.d.ts +11 -7
- package/dist/bridge/src/harness-model-check.d.ts.map +1 -1
- package/dist/bridge/src/harnesses/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/harnesses/codex.d.ts +0 -6
- package/dist/bridge/src/harnesses/codex.d.ts.map +1 -1
- package/dist/bridge/src/harnesses/omp.d.ts.map +1 -1
- package/dist/bridge/src/index.d.ts +1 -0
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/{chunk-XEVFSDIF.js → chunk-22ZX33H6.js} +6 -6
- package/dist/{chunk-XEVFSDIF.js.map → chunk-22ZX33H6.js.map} +1 -1
- package/dist/{chunk-KPKGWXUJ.js → chunk-23SG4JRV.js} +4 -4
- package/dist/{chunk-KPKGWXUJ.js.map → chunk-23SG4JRV.js.map} +1 -1
- package/dist/{chunk-MYXFR27L.js → chunk-2HS357RA.js} +77 -37
- package/dist/chunk-2HS357RA.js.map +1 -0
- package/dist/{chunk-7TSNR5H5.js → chunk-2IAWVUW3.js} +4 -4
- package/dist/{chunk-7TSNR5H5.js.map → chunk-2IAWVUW3.js.map} +1 -1
- package/dist/{chunk-6GWSDPBP.js → chunk-2M3VLKT2.js} +3 -3
- package/dist/{chunk-6GWSDPBP.js.map → chunk-2M3VLKT2.js.map} +1 -1
- package/dist/{chunk-PNUM7GUY.js → chunk-3DA74PLW.js} +3 -3
- package/dist/{chunk-PNUM7GUY.js.map → chunk-3DA74PLW.js.map} +1 -1
- package/dist/{chunk-7RH6E332.js → chunk-3KSLUVKB.js} +7 -7
- package/dist/{chunk-7RH6E332.js.map → chunk-3KSLUVKB.js.map} +1 -1
- package/dist/{chunk-6OHZUUR7.js → chunk-5DE3DGVR.js} +11 -5
- package/dist/chunk-5DE3DGVR.js.map +1 -0
- package/dist/{chunk-32FYVSSW.js → chunk-6EKQENAP.js} +6 -6
- package/dist/{chunk-32FYVSSW.js.map → chunk-6EKQENAP.js.map} +1 -1
- package/dist/{chunk-QK7AG5AV.js → chunk-6Y3SC7O4.js} +4 -4
- package/dist/{chunk-QK7AG5AV.js.map → chunk-6Y3SC7O4.js.map} +1 -1
- package/dist/{chunk-ROVZCGTN.js → chunk-7EMS2GZO.js} +40 -37
- package/dist/chunk-7EMS2GZO.js.map +1 -0
- package/dist/{chunk-COUJOTAJ.js → chunk-7H4GTP7V.js} +3 -3
- package/dist/{chunk-COUJOTAJ.js.map → chunk-7H4GTP7V.js.map} +1 -1
- package/dist/{chunk-VUWRGMT6.js → chunk-AFTZNR2W.js} +3 -3
- package/dist/{chunk-VUWRGMT6.js.map → chunk-AFTZNR2W.js.map} +1 -1
- package/dist/{chunk-JMIKGAUA.js → chunk-AVFRFGM2.js} +16 -6
- package/dist/chunk-AVFRFGM2.js.map +1 -0
- package/dist/{chunk-7MV3NHPT.js → chunk-B436SG5P.js} +42 -25
- package/dist/chunk-B436SG5P.js.map +1 -0
- package/dist/{chunk-ZEH4WFEG.js → chunk-B4BLJUYN.js} +69 -26
- package/dist/chunk-B4BLJUYN.js.map +1 -0
- package/dist/{chunk-LEJQAX7G.js → chunk-DNXPXJ3X.js} +82 -50
- package/dist/chunk-DNXPXJ3X.js.map +1 -0
- package/dist/{chunk-HDVLBEEX.js → chunk-E6UWI3TP.js} +3 -3
- package/dist/{chunk-HDVLBEEX.js.map → chunk-E6UWI3TP.js.map} +1 -1
- package/dist/{chunk-2TFKXSB5.js → chunk-EN5REMWV.js} +4 -4
- package/dist/{chunk-2TFKXSB5.js.map → chunk-EN5REMWV.js.map} +1 -1
- package/dist/{chunk-QFFMFZIR.js → chunk-EO7KGX6P.js} +4 -4
- package/dist/{chunk-QFFMFZIR.js.map → chunk-EO7KGX6P.js.map} +1 -1
- package/dist/{chunk-KIPCBIFJ.js → chunk-ETF6Q3R3.js} +23 -80
- package/dist/chunk-ETF6Q3R3.js.map +1 -0
- package/dist/{chunk-6WH2WE4B.js → chunk-G4NCSYWR.js} +9 -8
- package/dist/chunk-G4NCSYWR.js.map +1 -0
- package/dist/{chunk-JCPD4QRM.js → chunk-G5SYFFMD.js} +2 -2
- package/dist/{chunk-JCPD4QRM.js.map → chunk-G5SYFFMD.js.map} +1 -1
- package/dist/{chunk-Q7CU5GQO.js → chunk-HPA3RP5E.js} +4 -4
- package/dist/{chunk-Q7CU5GQO.js.map → chunk-HPA3RP5E.js.map} +1 -1
- package/dist/{chunk-KGHYXXXV.js → chunk-IS3NIZBX.js} +588 -133
- package/dist/chunk-IS3NIZBX.js.map +1 -0
- package/dist/{chunk-XBQTXGY4.js → chunk-IWKKTCXY.js} +98 -17
- package/dist/chunk-IWKKTCXY.js.map +1 -0
- package/dist/{chunk-HH2H2ZV7.js → chunk-J5JWLKLB.js} +35 -20
- package/dist/chunk-J5JWLKLB.js.map +1 -0
- package/dist/chunk-J6YPKMMY.js +83 -0
- package/dist/chunk-J6YPKMMY.js.map +1 -0
- package/dist/{chunk-TGV2EWGL.js → chunk-K4DHYTUM.js} +4 -4
- package/dist/{chunk-TGV2EWGL.js.map → chunk-K4DHYTUM.js.map} +1 -1
- package/dist/{chunk-72NT2TJU.js → chunk-KA2GLAPS.js} +7 -8
- package/dist/chunk-KA2GLAPS.js.map +1 -0
- package/dist/{chunk-VUJXZDCY.js → chunk-KSH5CFQS.js} +3 -3
- package/dist/{chunk-VUJXZDCY.js.map → chunk-KSH5CFQS.js.map} +1 -1
- package/dist/{chunk-BIRW3HOG.js → chunk-KSUT5KAE.js} +3 -3
- package/dist/{chunk-BIRW3HOG.js.map → chunk-KSUT5KAE.js.map} +1 -1
- package/dist/{chunk-AMJ6KEV7.js → chunk-KUADKMNX.js} +4 -4
- package/dist/{chunk-AMJ6KEV7.js.map → chunk-KUADKMNX.js.map} +1 -1
- package/dist/{chunk-TSTRH4SM.js → chunk-KYNCY3F3.js} +3 -3
- package/dist/{chunk-TSTRH4SM.js.map → chunk-KYNCY3F3.js.map} +1 -1
- package/dist/{chunk-V5BPDB4J.js → chunk-LE6QS4PG.js} +3 -3
- package/dist/{chunk-V5BPDB4J.js.map → chunk-LE6QS4PG.js.map} +1 -1
- package/dist/{chunk-6UP2EDFN.js → chunk-NSIOBKDX.js} +313 -4
- package/dist/chunk-NSIOBKDX.js.map +1 -0
- package/dist/{chunk-MD3FUZS3.js → chunk-OBZ5WQ32.js} +3 -3
- package/dist/{chunk-MD3FUZS3.js.map → chunk-OBZ5WQ32.js.map} +1 -1
- package/dist/{chunk-ELSGFI3I.js → chunk-OLHHN3NO.js} +31 -7
- package/dist/chunk-OLHHN3NO.js.map +1 -0
- package/dist/{chunk-JGH7NB47.js → chunk-S7DVT2BV.js} +4 -4
- package/dist/{chunk-JGH7NB47.js.map → chunk-S7DVT2BV.js.map} +1 -1
- package/dist/{chunk-PHAMYCZH.js → chunk-SN663FCA.js} +5 -5
- package/dist/{chunk-PHAMYCZH.js.map → chunk-SN663FCA.js.map} +1 -1
- package/dist/{serve-preflight-H2AYMGJ6.js → chunk-SRTWKZP2.js} +30 -61
- package/dist/chunk-SRTWKZP2.js.map +1 -0
- package/dist/{chunk-H622YULS.js → chunk-SZTHSPRC.js} +3 -4
- package/dist/chunk-SZTHSPRC.js.map +1 -0
- package/dist/{chunk-LD6O6QKU.js → chunk-T7HGEMNB.js} +4 -4
- package/dist/{chunk-LD6O6QKU.js.map → chunk-T7HGEMNB.js.map} +1 -1
- package/dist/{chunk-4QRJBY2P.js → chunk-TDPQOR3C.js} +2 -2
- package/dist/{chunk-4QRJBY2P.js.map → chunk-TDPQOR3C.js.map} +1 -1
- package/dist/{chunk-Y3I4KGLX.js → chunk-TGUMN5G7.js} +310 -175
- package/dist/chunk-TGUMN5G7.js.map +1 -0
- package/dist/{chunk-TO5SSMRI.js → chunk-THX5EE3K.js} +67 -19
- package/dist/chunk-THX5EE3K.js.map +1 -0
- package/dist/{chunk-QTLUZUF2.js → chunk-TNQLDEM6.js} +86 -34
- package/dist/chunk-TNQLDEM6.js.map +1 -0
- package/dist/{chunk-EQNIBBB6.js → chunk-TROEC2Z2.js} +34 -20
- package/dist/chunk-TROEC2Z2.js.map +1 -0
- package/dist/{chunk-E5NQRHEB.js → chunk-U6KRTCNA.js} +4 -4
- package/dist/{chunk-E5NQRHEB.js.map → chunk-U6KRTCNA.js.map} +1 -1
- package/dist/{chunk-J5JRGBKK.js → chunk-UMLCKKIA.js} +64 -32
- package/dist/chunk-UMLCKKIA.js.map +1 -0
- package/dist/{chunk-DU26AVK2.js → chunk-USVUS4DJ.js} +8 -8
- package/dist/{chunk-DU26AVK2.js.map → chunk-USVUS4DJ.js.map} +1 -1
- package/dist/{chunk-HGOJEVHY.js → chunk-UZET67SO.js} +4 -4
- package/dist/{chunk-HGOJEVHY.js.map → chunk-UZET67SO.js.map} +1 -1
- package/dist/{chunk-IZQOO6MN.js → chunk-V5KG6CCV.js} +2 -2
- package/dist/{chunk-IZQOO6MN.js.map → chunk-V5KG6CCV.js.map} +1 -1
- package/dist/{chunk-76FLBODK.js → chunk-VT6G5AJV.js} +10 -7
- package/dist/chunk-VT6G5AJV.js.map +1 -0
- package/dist/{chunk-URCJIV7T.js → chunk-W5KCAWGN.js} +3 -3
- package/dist/{chunk-URCJIV7T.js.map → chunk-W5KCAWGN.js.map} +1 -1
- package/dist/{chunk-YW4ASEUP.js → chunk-WFLQMAR5.js} +5 -5
- package/dist/{chunk-YW4ASEUP.js.map → chunk-WFLQMAR5.js.map} +1 -1
- package/dist/{chunk-RFQONXET.js → chunk-X44XKBZX.js} +3 -3
- package/dist/{chunk-RFQONXET.js.map → chunk-X44XKBZX.js.map} +1 -1
- package/dist/{chunk-BPTWWKGF.js → chunk-YBEJCQE5.js} +3 -3
- package/dist/{chunk-BPTWWKGF.js.map → chunk-YBEJCQE5.js.map} +1 -1
- package/dist/{chunk-PL52CI4U.js → chunk-YRC2EFOU.js} +4 -4
- package/dist/{chunk-PL52CI4U.js.map → chunk-YRC2EFOU.js.map} +1 -1
- package/dist/{chunk-7QG2WRSN.js → chunk-Z2X7UZEZ.js} +25 -8
- package/dist/chunk-Z2X7UZEZ.js.map +1 -0
- package/dist/{chunk-U3SXCVR7.js → chunk-ZUU2PLA3.js} +4 -4
- package/dist/{chunk-U3SXCVR7.js.map → chunk-ZUU2PLA3.js.map} +1 -1
- package/dist/{claude-code-EUKDGOOO.js → claude-code-JY6CYEG7.js} +4 -4
- package/dist/{claude-code-EUKDGOOO.js.map → claude-code-JY6CYEG7.js.map} +1 -1
- package/dist/cli/index.js +322 -162
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/cache.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/config.d.ts.map +1 -1
- package/dist/cli/src/commands/connector.d.ts.map +1 -1
- package/dist/cli/src/commands/deploy.d.ts.map +1 -1
- package/dist/cli/src/commands/harness.d.ts +5 -4
- package/dist/cli/src/commands/harness.d.ts.map +1 -1
- package/dist/cli/src/commands/integration.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-index.d.ts +6 -0
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-files.d.ts +3 -6
- package/dist/cli/src/commands/migrate-files.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-harness.d.ts +4 -3
- package/dist/cli/src/commands/migrate-harness.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate.d.ts +2 -2
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/preset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +7 -1
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/commands/serve-preflight.d.ts +21 -0
- package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
- package/dist/cli/src/commands/serve.d.ts.map +1 -1
- package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +8 -0
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/commands/validate-instances.d.ts +6 -0
- package/dist/cli/src/commands/validate-instances.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/commands/verify.d.ts.map +1 -1
- package/dist/cli/src/config-checks.d.ts +8 -0
- package/dist/cli/src/config-checks.d.ts.map +1 -1
- package/dist/cli/src/ensure-sources.d.ts.map +1 -1
- package/dist/cli/src/helpers.d.ts +13 -4
- package/dist/cli/src/helpers.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/index.d.ts +1 -1
- package/dist/cli/src/plugin-store/index.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/reconcile.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/spec.d.ts +20 -14
- package/dist/cli/src/plugin-store/spec.d.ts.map +1 -1
- package/dist/cli/src/setup.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +2 -0
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +23 -24
- package/dist/connectors/src/index.d.ts +2 -2
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors/src/managed-gitconfig.d.ts +22 -0
- package/dist/connectors/src/managed-gitconfig.d.ts.map +1 -1
- package/dist/connectors/src/npm-installer.d.ts +11 -3
- package/dist/connectors/src/npm-installer.d.ts.map +1 -1
- package/dist/connectors-VLFOQNS6.js +49 -0
- package/dist/{connectors-XYPE2DCQ.js.map → connectors-VLFOQNS6.js.map} +1 -1
- package/dist/connectors-shared/index.js +2 -2
- package/dist/core/index.js +6 -6
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/publish-manifest.js +3 -3
- package/dist/core/ref.js +1 -1
- package/dist/core/runtime-assets.js +5 -5
- package/dist/core/src/agent-instances.d.ts +6 -0
- package/dist/core/src/agent-instances.d.ts.map +1 -1
- package/dist/core/src/config-key-diagnostics.d.ts +2 -1
- package/dist/core/src/config-key-diagnostics.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +5 -5
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +20 -1
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/manifest-yaml-editor.d.ts +4 -1
- package/dist/core/src/manifest-yaml-editor.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +9 -3
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +10 -0
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +11 -0
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/runtime-assets.d.ts +12 -1
- package/dist/core/src/runtime-assets.d.ts.map +1 -1
- package/dist/core/src/walker.d.ts +3 -0
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +19 -2
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +6 -6
- package/dist/discovery/index.js +5 -5
- package/dist/{ensure-sources-IN3VKHUA.js → ensure-sources-6O54DUQB.js} +31 -31
- package/dist/ensure-sources-6O54DUQB.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +23 -24
- package/dist/factory-assets/connectors/deploy.js +23 -24
- package/dist/factory-assets/connectors/devserver.js +23 -24
- package/dist/factory-assets/connectors/flow/adapter.js +23 -24
- package/dist/factory-assets/connectors/flow/engine.js +7 -7
- package/dist/factory-assets/connectors/flow/run-flow.js +25 -26
- package/dist/factory-assets/connectors/flow.js +23 -24
- package/dist/factory-assets/connectors/git.js +23 -24
- package/dist/factory-assets/connectors/gmail.js +23 -24
- package/dist/factory-assets/connectors/googledrive.js +23 -24
- package/dist/factory-assets/connectors/local.js +23 -24
- package/dist/factory-assets/connectors/mattermost.js +23 -24
- package/dist/factory-assets/connectors/memory.js +23 -24
- package/dist/factory-assets/connectors/minio.js +23 -24
- package/dist/factory-assets/connectors/postgres.js +23 -24
- package/dist/factory-assets/connectors/s3.js +23 -24
- package/dist/factory-assets/connectors/sharepoint.js +23 -24
- package/dist/factory-assets/connectors/sqlite.js +23 -24
- package/dist/factory-assets/connectors/static-server.js +23 -24
- package/dist/factory-assets/connectors/tunnel.js +23 -24
- package/dist/factory-assets/connectors/webdav.js +23 -24
- package/dist/factory-assets/connectors/xstate-store.js +23 -24
- package/dist/factory-assets/connectors/xstate.js +23 -24
- package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +2 -1
- package/dist/{flows-QAO63TDV.js → flows-CIUPK7SB.js} +11 -11
- package/dist/{flows-QAO63TDV.js.map → flows-CIUPK7SB.js.map} +1 -1
- package/dist/{helpers-HDVGCF3M.js → helpers-YHDQHQEQ.js} +28 -29
- package/dist/{helpers-HDVGCF3M.js.map → helpers-YHDQHQEQ.js.map} +1 -1
- package/dist/library/index.js +10 -10
- package/dist/library/install.js +4 -4
- package/dist/library/src/manifest-writer.d.ts +9 -0
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts +9 -0
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/library/src/remote/rest-catalog-source.d.ts +1 -0
- package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
- package/dist/{library-publish-62OWCNB5.js → library-publish-MUGUST43.js} +53 -53
- package/dist/{library-publish-62OWCNB5.js.map → library-publish-MUGUST43.js.map} +1 -1
- package/dist/model-endpoint/index.js +9 -10
- package/dist/open-library-BVQCB37E.js +57 -0
- package/dist/{open-library-TZ7OSDEJ.js.map → open-library-BVQCB37E.js.map} +1 -1
- package/dist/{open-registry-RLZKTJG3.js → open-registry-JCSIAKEC.js} +14 -14
- package/dist/{open-registry-RLZKTJG3.js.map → open-registry-JCSIAKEC.js.map} +1 -1
- package/dist/{paths-D6LBQETQ.js → paths-XLKCAFRZ.js} +9 -9
- package/dist/{paths-D6LBQETQ.js.map → paths-XLKCAFRZ.js.map} +1 -1
- package/dist/{plugin-store-A5J4TLCH.js → plugin-store-NGRUTCJI.js} +9 -9
- package/dist/{plugin-store-A5J4TLCH.js.map → plugin-store-NGRUTCJI.js.map} +1 -1
- package/dist/project-BGYMLAS6.js +88 -0
- package/dist/{project-4AVRES3M.js.map → project-BGYMLAS6.js.map} +1 -1
- package/dist/resolver/index.js +7 -7
- package/dist/runner/index.js +38 -39
- package/dist/runner/src/capability-roundtrip.d.ts +4 -1
- package/dist/runner/src/capability-roundtrip.d.ts.map +1 -1
- package/dist/runner/src/composition/resolve-instance.d.ts.map +1 -1
- package/dist/runner/src/composition/resolve.d.ts +6 -0
- package/dist/runner/src/composition/resolve.d.ts.map +1 -1
- package/dist/runner/src/credential-notice.d.ts +3 -2
- package/dist/runner/src/credential-notice.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +13 -13
- package/dist/sdk/bridge.js +19 -20
- package/dist/sdk/core.js +6 -6
- package/dist/sdk/flow.js +7 -7
- package/dist/sdk/index.js +38 -39
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +7 -7
- package/dist/sdk/runner.js +38 -39
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/transport/ws/server.js +7 -7
- package/dist/sdk/transport/ws.js +7 -7
- package/dist/sdk/transport.js +7 -7
- package/dist/sdk/types.js +1 -1
- package/dist/serve-preflight-GQY5DZX6.js +56 -0
- package/dist/serve-preflight-GQY5DZX6.js.map +1 -0
- package/dist/session/index.js +2 -2
- package/dist/{setup-NSPQD4V4.js → setup-2NWSKSCO.js} +34 -32
- package/dist/setup-2NWSKSCO.js.map +1 -0
- package/dist/{skills-B533SRVZ.js → skills-PXZOL2FZ.js} +12 -12
- package/dist/{skills-B533SRVZ.js.map → skills-PXZOL2FZ.js.map} +1 -1
- package/dist/source-XA3L4H6I.js +86 -0
- package/dist/{source-VTECABUO.js.map → source-XA3L4H6I.js.map} +1 -1
- package/dist/{source-manifest-publish-YORI42MN.js → source-manifest-publish-QEGMTS33.js} +50 -51
- package/dist/source-manifest-publish-QEGMTS33.js.map +1 -0
- package/dist/transport/index.js +7 -7
- package/dist/transport/ws/server.js +7 -7
- package/dist/transport/ws.js +7 -7
- package/dist/tui/index.js +38 -39
- package/dist/tui/index.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/capabilities.d.ts +9 -1
- package/dist/types/src/capabilities.d.ts.map +1 -1
- package/dist/types/src/manifests/agent.d.ts +2 -2
- package/dist/types/src/manifests/agent.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +8 -8
- package/dist/workspace-plugin/adapters/mcp.js +30 -31
- package/dist/workspace-plugin/adapters/omp.js +14 -14
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-6OHZUUR7.js.map +0 -1
- package/dist/chunk-6UP2EDFN.js.map +0 -1
- package/dist/chunk-6WH2WE4B.js.map +0 -1
- package/dist/chunk-72NT2TJU.js.map +0 -1
- package/dist/chunk-76FLBODK.js.map +0 -1
- package/dist/chunk-7MV3NHPT.js.map +0 -1
- package/dist/chunk-7QG2WRSN.js.map +0 -1
- package/dist/chunk-ELSGFI3I.js.map +0 -1
- package/dist/chunk-EQNIBBB6.js.map +0 -1
- package/dist/chunk-H622YULS.js.map +0 -1
- package/dist/chunk-HH2H2ZV7.js.map +0 -1
- package/dist/chunk-J5JRGBKK.js.map +0 -1
- package/dist/chunk-JMIKGAUA.js.map +0 -1
- package/dist/chunk-KGHYXXXV.js.map +0 -1
- package/dist/chunk-KIPCBIFJ.js.map +0 -1
- package/dist/chunk-LEJQAX7G.js.map +0 -1
- package/dist/chunk-MYXFR27L.js.map +0 -1
- package/dist/chunk-QTLUZUF2.js.map +0 -1
- package/dist/chunk-ROVZCGTN.js.map +0 -1
- package/dist/chunk-S6KZHPR4.js +0 -315
- package/dist/chunk-S6KZHPR4.js.map +0 -1
- package/dist/chunk-TO5SSMRI.js.map +0 -1
- package/dist/chunk-XBQTXGY4.js.map +0 -1
- package/dist/chunk-Y3I4KGLX.js.map +0 -1
- package/dist/chunk-ZEH4WFEG.js.map +0 -1
- package/dist/connectors-XYPE2DCQ.js +0 -50
- package/dist/ensure-sources-IN3VKHUA.js.map +0 -1
- package/dist/open-library-TZ7OSDEJ.js +0 -58
- package/dist/project-4AVRES3M.js +0 -88
- package/dist/serve-preflight-H2AYMGJ6.js.map +0 -1
- package/dist/setup-NSPQD4V4.js.map +0 -1
- package/dist/source-VTECABUO.js +0 -87
- package/dist/source-manifest-publish-YORI42MN.js.map +0 -1
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, missingRootAssets, storeManifestFile, missingLibraryDirMessage, lastLibraryName, filesEntryPaths } from './chunk-
|
|
2
|
-
import { SEMVER_RE, invalidSemverMessage, flowFileNameError, computeDeterministicHash, readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-
|
|
1
|
+
import { unregisteredLibraryNames, renamedLibraryName, resolveConfig, RemoteCatalogSource, OfflineError, describeCatalogError, CatalogHttpError, scanUnlistedAssets, missingRootAssets, storeManifestFile, missingLibraryDirMessage, lastLibraryName, filesEntryPaths } from './chunk-TGUMN5G7.js';
|
|
2
|
+
import { SEMVER_RE, invalidSemverMessage, flowFileNameError, computeDeterministicHash, readManifestSourceConfig, discoverAssetsInTree, isManifestMode } from './chunk-22ZX33H6.js';
|
|
3
3
|
import { parseFlowDefinition } from './chunk-JRN5QF4C.js';
|
|
4
|
-
import { installTargetOf, readKeptLegacyCopies, writeKeptLegacyCopies, canonicalEntryRef, diffDeployedAgent, deployedAssetDrift, assertNoLibrarySymlinks, deployAll, removeAsset, composedDriftRefs, sourceComposedFiles, cachedComposedFiles, createScaffold, installAgent } from './chunk-
|
|
4
|
+
import { installTargetOf, readKeptLegacyCopies, writeKeptLegacyCopies, canonicalEntryRef, diffDeployedAgent, deployedAssetDrift, entriesNeedingDeploy, assertNoLibrarySymlinks, deployAll, removeAsset, composedDriftRefs, sourceComposedFiles, cachedComposedFiles, createScaffold, installAgent } from './chunk-2HS357RA.js';
|
|
5
5
|
import { appendHistory, getRecentHistory, clearHistory } from './chunk-KTBKW2FI.js';
|
|
6
6
|
import { commitChanges } from './chunk-UQ6LFBPZ.js';
|
|
7
|
-
import { harnessTargetSupportsAgents, CODEX_IDENTITY_DIR, agentRenderFiles } from './chunk-
|
|
8
|
-
import { isScaffoldBody, isScaffoldDescription } from './chunk-
|
|
9
|
-
import { resolveConfiguredHarnessName, FACTORY_SOURCE_URL, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, writeLock, computeHash, buildLockFile, readLock, assertLockHashes, verifyLock, mergeLockFile, resyncLockSources, extractForPatch, generatePatch, savePatch, applyPatch, LOCK_SCHEMA_VERSION } from './chunk-
|
|
10
|
-
import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-
|
|
7
|
+
import { harnessTargetSupportsAgents, CODEX_IDENTITY_DIR, agentRenderFiles } from './chunk-T7HGEMNB.js';
|
|
8
|
+
import { isScaffoldBody, isScaffoldDescription } from './chunk-VT6G5AJV.js';
|
|
9
|
+
import { resolveConfiguredHarnessName, FACTORY_SOURCE_URL, isFactoryMemorySource, GLOBAL_INSTALL_DIR_NAME, resolveLibraryDir, buildLibraryLockEntries, writeLock, computeHash, buildLockFile, readLock, LockParseError, assertLockHashes, verifyLock, mergeLockFile, resyncLockSources, extractForPatch, generatePatch, savePatch, applyPatch, LOCK_SCHEMA_VERSION } from './chunk-UMLCKKIA.js';
|
|
10
|
+
import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-G4NCSYWR.js';
|
|
11
11
|
import { deployedBase, isDeployed, deployedPaths, deployedDir } from './chunk-5KRMNUL4.js';
|
|
12
|
-
import { resolveSkWorkspaceConfig, effectiveAgentInstances, mcpDeclarationFromMdContent, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, readLinks, isCommitOnRemote, findWorkspaceRoot, resolveAll, agentSourceCacheDir, ensureRepo, resolveAgentDefinitionDir, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, MAX_PRESET_DEPTH, PresetDepthError
|
|
12
|
+
import { resolveSkWorkspaceConfig, effectiveAgentInstances, mcpDeclarationFromMdContent, loadMcpServerDeclarations, resolveGlobalHarnesses, resolveGlobalSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, matchPin, buildProvenanceIndex, coerceVersion, sourceShortName, readLinks, isCommitOnRemote, findWorkspaceRoot, resolveSourcePublisher, resolveAll, agentSourceCacheDir, ensureRepo, resolveAgentDefinitionDir, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, DEFAULT_AGENT_INSTANCE_ID, MAX_PRESET_DEPTH, PresetDepthError } from './chunk-IWKKTCXY.js';
|
|
13
13
|
import { globalSkaileDir, globalCacheRoot, migrateLegacyDir } from './chunk-L5VSIPQD.js';
|
|
14
14
|
import { HARNESS_TARGETS, SUPPORTED_HARNESSES } from './chunk-VTETQCR6.js';
|
|
15
|
-
import { listAssetFiles, loadSkPublishManifest, decodeSkaileManifest, isNonAssetDir, isNonAssetFile } from './chunk-
|
|
16
|
-
import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements, readAssetBody } from './chunk-
|
|
17
|
-
import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-
|
|
15
|
+
import { listAssetFiles, loadSkPublishManifest, decodeSkaileManifest, isNonAssetDir, isNonAssetFile } from './chunk-23SG4JRV.js';
|
|
16
|
+
import { scanDirectory, parseFrontmatter, parseRequires, dedupeRequirements, readAssetBody } from './chunk-AVFRFGM2.js';
|
|
17
|
+
import { parseAssetRef, parseAssetRefLoose, assetRefToStr, slugifyAssetName, depToStr, parseDep } from './chunk-V5KG6CCV.js';
|
|
18
18
|
import { spawnSync } from 'child_process';
|
|
19
|
-
import { existsSync, rmSync, readFileSync, writeFileSync, readdirSync, lstatSync, statSync, unlinkSync, mkdirSync } from 'fs';
|
|
19
|
+
import { existsSync, rmSync, readFileSync, writeFileSync, readdirSync, lstatSync, statSync, realpathSync, unlinkSync, mkdirSync } from 'fs';
|
|
20
20
|
import { homedir } from 'os';
|
|
21
|
-
import path, { resolve, dirname, sep, join, relative, posix } from 'path';
|
|
21
|
+
import path, { resolve, dirname, sep, join, relative, isAbsolute, posix } from 'path';
|
|
22
22
|
import { gt } from 'semver';
|
|
23
23
|
import { parse, stringify } from 'yaml';
|
|
24
24
|
import { createHash } from 'crypto';
|
|
@@ -128,10 +128,18 @@ function removeAgentInstanceRenderings(opts) {
|
|
|
128
128
|
}
|
|
129
129
|
return removed;
|
|
130
130
|
}
|
|
131
|
+
function readInstanceFile(abs) {
|
|
132
|
+
try {
|
|
133
|
+
return statSync(abs).isDirectory() ? "\0dir" : readFileSync(abs, "utf-8");
|
|
134
|
+
} catch {
|
|
135
|
+
return void 0;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
131
138
|
function installAgentInstances(opts) {
|
|
132
139
|
const { projectDir, harness, log } = opts;
|
|
133
140
|
const result = {
|
|
134
141
|
instances: [],
|
|
142
|
+
changed: [],
|
|
135
143
|
removed: [],
|
|
136
144
|
warnings: [],
|
|
137
145
|
errors: []
|
|
@@ -151,6 +159,9 @@ function installAgentInstances(opts) {
|
|
|
151
159
|
if (previous[id]) owned[id] = previous[id];
|
|
152
160
|
continue;
|
|
153
161
|
}
|
|
162
|
+
const before = /* @__PURE__ */ new Map();
|
|
163
|
+
for (const rel of previous[id] ?? [])
|
|
164
|
+
before.set(rel, readInstanceFile(resolve(projectDir, rel)));
|
|
154
165
|
const rendered = installAgent(
|
|
155
166
|
srcDir,
|
|
156
167
|
agentDeployDir,
|
|
@@ -169,6 +180,13 @@ function installAgentInstances(opts) {
|
|
|
169
180
|
const files = [...new Set(rendered.created)];
|
|
170
181
|
owned[id] = files;
|
|
171
182
|
result.instances.push({ id, files });
|
|
183
|
+
const sameFiles = files.length === before.size && files.every((rel) => before.has(rel));
|
|
184
|
+
if (!sameFiles || files.some((rel) => {
|
|
185
|
+
const old = before.get(rel);
|
|
186
|
+
return old === void 0 || readInstanceFile(resolve(projectDir, rel)) !== old;
|
|
187
|
+
})) {
|
|
188
|
+
result.changed.push(id);
|
|
189
|
+
}
|
|
172
190
|
}
|
|
173
191
|
const claimed = new Set(Object.values(owned).flat());
|
|
174
192
|
const root = resolve(projectDir);
|
|
@@ -803,6 +821,10 @@ function lockedAssetFiles(kind, files) {
|
|
|
803
821
|
});
|
|
804
822
|
}
|
|
805
823
|
var GITHUB_REPO_URL = /github\.com[/:]/i;
|
|
824
|
+
function isBundledFactoryEntry(entry) {
|
|
825
|
+
if (isFactoryMemorySource(entry.source)) return true;
|
|
826
|
+
return entry.origin === void 0 && entry.source !== void 0 && normalizeRepoUrl(entry.source.url) === normalizeRepoUrl(FACTORY_SOURCE_URL);
|
|
827
|
+
}
|
|
806
828
|
var GIT_URL = /^(?:[a-z][a-z0-9+.-]*:\/\/|[\w.-]+@[\w.-]+:)/i;
|
|
807
829
|
function indexLockByKindName(lock) {
|
|
808
830
|
const lockByKindName = /* @__PURE__ */ new Map();
|
|
@@ -1403,6 +1425,8 @@ var AssetManager = class {
|
|
|
1403
1425
|
warnedStoreVersionLookups = /* @__PURE__ */ new Set();
|
|
1404
1426
|
/** Stores a lookup could not reach (store URL -> one line why); `add` reports them instead of "not found". */
|
|
1405
1427
|
storeFailures = /* @__PURE__ */ new Map();
|
|
1428
|
+
/** Source origins `outdated` could not fetch; read once through {@link takeUnreachableSources}. */
|
|
1429
|
+
unreachableSources = [];
|
|
1406
1430
|
/** Store URLs a lookup failed on because the client is air-gapped (`cache_ttl: 0`), not because the store is down. */
|
|
1407
1431
|
airGappedStores = /* @__PURE__ */ new Set();
|
|
1408
1432
|
/** Sources a provenance walk had to skip (source URL → why); one warning per source. */
|
|
@@ -1504,13 +1528,38 @@ var AssetManager = class {
|
|
|
1504
1528
|
});
|
|
1505
1529
|
}
|
|
1506
1530
|
/**
|
|
1507
|
-
*
|
|
1508
|
-
*
|
|
1509
|
-
*
|
|
1510
|
-
*
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1531
|
+
* The harness a 5.12.0 `add --global --harness omp` left as the asset's only copy: the copy sits
|
|
1532
|
+
* under the 5.12.0 omp folder (`~/.omp/skills`) and no other default harness holds one. That
|
|
1533
|
+
* folder is the only real 5.12.0 evidence: a current `add --global` writes no row either, so a
|
|
1534
|
+
* lone copy elsewhere may be a copy the user deleted or a harness added later (p1442).
|
|
1535
|
+
*/
|
|
1536
|
+
legacySingleCopyHarness(component, name, all) {
|
|
1537
|
+
if (!all.includes("omp") || legacyOmpPaths(component, name).length === 0) return [];
|
|
1538
|
+
const others = all.filter((h) => h !== "omp" && isDeployed(component, name, h, true));
|
|
1539
|
+
return others.length === 0 ? ["omp"] : [];
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* Whether `~/.skaile/skaile.yaml` is a 5.12.0 record: it exists and has no
|
|
1543
|
+
* `global_asset_harnesses:` key yet, so {@link inferLegacyHarnessSubsets} has not run.
|
|
1544
|
+
*/
|
|
1545
|
+
isLegacyHarnessRecord() {
|
|
1546
|
+
if (!this.global) return false;
|
|
1547
|
+
const configPath = join(this.stateRoot, "skaile.yaml");
|
|
1548
|
+
if (!existsSync(configPath)) return false;
|
|
1549
|
+
try {
|
|
1550
|
+
const raw = parse(readFileSync(configPath, "utf8"));
|
|
1551
|
+
return !!raw && typeof raw === "object" && !(ENTRY_HARNESSES_KEY in raw);
|
|
1552
|
+
} catch {
|
|
1553
|
+
return false;
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
/**
|
|
1557
|
+
* A 5.12.0 global record has no `global_asset_harnesses:` key, yet `add --global --harness omp`
|
|
1558
|
+
* wrote one copy only, under `~/.omp/skills`. On the first global `install`, an entry whose only
|
|
1559
|
+
* copy sits there (see {@link legacySingleCopyHarness}) is omp's subset (OQ6): record it, so the
|
|
1560
|
+
* install does not fan the asset out to harnesses the user never asked for (p1442). Nothing is
|
|
1561
|
+
* inferred without that evidence, once the key exists (an entry without a row then means "every
|
|
1562
|
+
* harness"), or with one default harness. Global mode only; returns the rows written.
|
|
1514
1563
|
*/
|
|
1515
1564
|
inferLegacyHarnessSubsets(entries) {
|
|
1516
1565
|
if (!this.global) return [];
|
|
@@ -1529,9 +1578,7 @@ var AssetManager = class {
|
|
|
1529
1578
|
for (const e of entries) {
|
|
1530
1579
|
const component = this.installTarget(e.kind);
|
|
1531
1580
|
if (!component || !e.name) continue;
|
|
1532
|
-
const holding =
|
|
1533
|
-
(h) => isDeployed(component, e.name, h, true) || h === "omp" && legacyOmpPaths(component, e.name).length > 0
|
|
1534
|
-
);
|
|
1581
|
+
const holding = this.legacySingleCopyHarness(component, e.name, all);
|
|
1535
1582
|
if (holding.length !== 1) continue;
|
|
1536
1583
|
const publisher = e.publisher?.replace(/^@/, "");
|
|
1537
1584
|
const ref = `${e.kind}:${publisher ? `@${publisher}/` : ""}${e.name}`;
|
|
@@ -1702,6 +1749,13 @@ var AssetManager = class {
|
|
|
1702
1749
|
takeLegacyCopiesRemoved() {
|
|
1703
1750
|
return this.legacyCopiesRemoved.splice(0);
|
|
1704
1751
|
}
|
|
1752
|
+
/**
|
|
1753
|
+
* The source origins the last {@link outdated} call could not fetch (name, URL, why). Their
|
|
1754
|
+
* behind count was not checked, so the CLI must not call the project up to date (p1820).
|
|
1755
|
+
*/
|
|
1756
|
+
takeUnreachableSources() {
|
|
1757
|
+
return this.unreachableSources.splice(0);
|
|
1758
|
+
}
|
|
1705
1759
|
/**
|
|
1706
1760
|
* The harnesses `add` / `install` deploy into: `[harness]` for a project, the global
|
|
1707
1761
|
* harness set (see {@link AssetManager.targetHarnesses}) for a global manager.
|
|
@@ -1920,6 +1974,7 @@ var AssetManager = class {
|
|
|
1920
1974
|
for (const w of [...result.warnings, ...result.errors]) console.warn(`skaile: ${w}`);
|
|
1921
1975
|
return {
|
|
1922
1976
|
agentInstances: result.instances,
|
|
1977
|
+
agentInstancesChanged: result.changed,
|
|
1923
1978
|
agentFilesRemoved: result.removed,
|
|
1924
1979
|
...result.errors.length > 0 ? { agentInstanceErrors: result.errors } : {},
|
|
1925
1980
|
...details.length > 0 ? { agentInstanceDetails: details } : {}
|
|
@@ -1950,11 +2005,7 @@ var AssetManager = class {
|
|
|
1950
2005
|
};
|
|
1951
2006
|
}
|
|
1952
2007
|
const factory = resolveFactorySource();
|
|
1953
|
-
|
|
1954
|
-
const alreadyDeclared = Object.values(repositories).some(
|
|
1955
|
-
(d) => d.url !== void 0 && normalizeRepoUrl(d.url) === factoryUrl
|
|
1956
|
-
);
|
|
1957
|
-
if (factory && !alreadyDeclared && !repositories[factory.publisher]) {
|
|
2008
|
+
if (factory && !repositories[factory.publisher]) {
|
|
1958
2009
|
repositories[factory.publisher] = {
|
|
1959
2010
|
path: factory.dir,
|
|
1960
2011
|
url: FACTORY_SOURCE_URL,
|
|
@@ -1969,7 +2020,7 @@ var AssetManager = class {
|
|
|
1969
2020
|
for (const [slug, decl] of Object.entries(repositories)) {
|
|
1970
2021
|
const localPath = this.resolveRepoDir(decl, slug);
|
|
1971
2022
|
if (!localPath || !existsSync(localPath)) continue;
|
|
1972
|
-
if (decl.url &&
|
|
2023
|
+
if (decl.url && !decl.factory && !existsSync(join(localPath, ".git"))) {
|
|
1973
2024
|
this.reportSourceError(
|
|
1974
2025
|
{ localPath, sourceUrl: decl.url, commit: "" },
|
|
1975
2026
|
new Error(
|
|
@@ -2066,8 +2117,8 @@ var AssetManager = class {
|
|
|
2066
2117
|
const { publisher, kind, name, version } = parseCanonicalLockKey(key);
|
|
2067
2118
|
if (!publisher || !kind || !name) return null;
|
|
2068
2119
|
const url = entry.source.url;
|
|
2069
|
-
const factory = Object.values(repositories).find((d) => d.factory);
|
|
2070
|
-
const declared = factory
|
|
2120
|
+
const factory = isFactoryMemorySource(entry.source) ? Object.values(repositories).find((d) => d.factory) : void 0;
|
|
2121
|
+
const declared = factory ?? repositories[sourceCacheKey(url)];
|
|
2071
2122
|
return {
|
|
2072
2123
|
publisher,
|
|
2073
2124
|
kind,
|
|
@@ -2378,7 +2429,6 @@ var AssetManager = class {
|
|
|
2378
2429
|
knownKinds: this.knownKinds,
|
|
2379
2430
|
onSourceError: this.reportSourceError
|
|
2380
2431
|
});
|
|
2381
|
-
const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
|
|
2382
2432
|
const hasFactory = Object.values(repositories).some((d) => d.factory);
|
|
2383
2433
|
const out = /* @__PURE__ */ new Map();
|
|
2384
2434
|
const originsOf = (key) => {
|
|
@@ -2402,7 +2452,7 @@ var AssetManager = class {
|
|
|
2402
2452
|
return a.sourceUrl.localeCompare(b.sourceUrl);
|
|
2403
2453
|
});
|
|
2404
2454
|
for (const c of held) {
|
|
2405
|
-
const factory = hasFactory &&
|
|
2455
|
+
const factory = hasFactory && isFactoryMemorySource({ url: c.sourceUrl, commit: c.commit });
|
|
2406
2456
|
originsOf(key).push({
|
|
2407
2457
|
kind: factory ? "factory" : "source",
|
|
2408
2458
|
label: factory ? "factory" : sourceShortName(c.sourceUrl),
|
|
@@ -2826,7 +2876,8 @@ var AssetManager = class {
|
|
|
2826
2876
|
});
|
|
2827
2877
|
}
|
|
2828
2878
|
/**
|
|
2829
|
-
* Open the local index and snapshot its libraries + asset definitions
|
|
2879
|
+
* Open the local index and snapshot its libraries + asset definitions, scoped to this
|
|
2880
|
+
* project's `sources:` ({@link scopeLibraryIndex}).
|
|
2830
2881
|
* Best-effort: no index file (never indexed), or any open/guard failure,
|
|
2831
2882
|
* yields `null` — a lock/outdated read must never create `index.db` or throw.
|
|
2832
2883
|
*/
|
|
@@ -2837,14 +2888,7 @@ var AssetManager = class {
|
|
|
2837
2888
|
if (!existsSync(indexPath)) return null;
|
|
2838
2889
|
const index = new LocalIndex({ indexPath });
|
|
2839
2890
|
try {
|
|
2840
|
-
|
|
2841
|
-
const defs = await index.listAssetDefs();
|
|
2842
|
-
const hidden = this.undeclaredSourceClones(libraries);
|
|
2843
|
-
if (hidden.size === 0) return { libraries, defs };
|
|
2844
|
-
return {
|
|
2845
|
-
libraries: libraries.filter((l) => !hidden.has(l.id)),
|
|
2846
|
-
defs: defs.filter((d) => !d.libraryId || !hidden.has(d.libraryId))
|
|
2847
|
-
};
|
|
2891
|
+
return this.scopeLibraryIndex(await index.listSources(), await index.listAssetDefs());
|
|
2848
2892
|
} finally {
|
|
2849
2893
|
index.close();
|
|
2850
2894
|
}
|
|
@@ -2852,32 +2896,85 @@ var AssetManager = class {
|
|
|
2852
2896
|
return null;
|
|
2853
2897
|
}
|
|
2854
2898
|
}
|
|
2899
|
+
/**
|
|
2900
|
+
* The `sources:` this project declares by clone key, or `undefined` outside a project (no
|
|
2901
|
+
* `skaile.yaml` in `projectDir` or a parent) or when the file does not parse. Outside a
|
|
2902
|
+
* project nothing declares sources, so the machine-wide search reads every clone.
|
|
2903
|
+
*/
|
|
2904
|
+
declaredSourceEntries() {
|
|
2905
|
+
if (!this.global && !findWorkspaceRoot(this.projectDir)) return void 0;
|
|
2906
|
+
try {
|
|
2907
|
+
return new Map(this.loadConfig().sources.map((s) => [sourceCacheKey(s.url), s]));
|
|
2908
|
+
} catch {
|
|
2909
|
+
return void 0;
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
/** The clone-cache key a source-clone reader row stands for, or `undefined` for any other library. */
|
|
2913
|
+
sourceCloneKey(l) {
|
|
2914
|
+
if (l.ownership !== "reader" || !("url" in l.backendConfig)) return void 0;
|
|
2915
|
+
const cloneRoots = [
|
|
2916
|
+
join(globalCacheRoot(), "sources"),
|
|
2917
|
+
join(globalSkaileDir(), "sources"),
|
|
2918
|
+
this.reposDir
|
|
2919
|
+
].map((d) => resolve(d));
|
|
2920
|
+
const at = resolve(l.path);
|
|
2921
|
+
return cloneRoots.some((root) => at.startsWith(root + sep)) ? sourceCacheKey(l.backendConfig.url) : void 0;
|
|
2922
|
+
}
|
|
2855
2923
|
/**
|
|
2856
2924
|
* Ids of the registered libraries that are the clone of a source this project does not
|
|
2857
2925
|
* declare. `source add` registers the clone as a machine-wide reader library so `search`
|
|
2858
2926
|
* and the indexer can read it, but a `sources:` clone belongs to the projects that declare
|
|
2859
|
-
* it (
|
|
2927
|
+
* it (OQ4, p321): another project neither resolves it, nor ties with it by name, nor has
|
|
2860
2928
|
* `update` re-pin its locked assets to it. A reader library the user registered by hand
|
|
2861
2929
|
* (`library init --reader --git`) lives outside the sources cache and is never hidden.
|
|
2862
2930
|
*/
|
|
2863
2931
|
undeclaredSourceClones(libraries) {
|
|
2864
2932
|
const hidden = /* @__PURE__ */ new Set();
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
try {
|
|
2868
|
-
declared = new Set(this.loadConfig().sources.map((s) => sourceCacheKey(s.url)));
|
|
2869
|
-
} catch {
|
|
2870
|
-
return hidden;
|
|
2871
|
-
}
|
|
2872
|
-
const cloneRoots = [join(globalCacheRoot(), "sources"), this.reposDir].map((d) => resolve(d));
|
|
2933
|
+
const declared = this.declaredSourceEntries();
|
|
2934
|
+
if (!declared) return hidden;
|
|
2873
2935
|
for (const l of libraries) {
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
if (!cloneRoots.some((root) => at.startsWith(root + sep))) continue;
|
|
2877
|
-
if (!declared.has(sourceCacheKey(l.backendConfig.url))) hidden.add(l.id);
|
|
2936
|
+
const key = this.sourceCloneKey(l);
|
|
2937
|
+
if (key !== void 0 && !declared.has(key)) hidden.add(l.id);
|
|
2878
2938
|
}
|
|
2879
2939
|
return hidden;
|
|
2880
2940
|
}
|
|
2941
|
+
/**
|
|
2942
|
+
* The index as this project sees it: the source clones of other projects are dropped
|
|
2943
|
+
* ({@link undeclaredSourceClones}) and the assets of a declared source carry the publisher
|
|
2944
|
+
* this project's `sources:` entry names. The clone and its index rows are shared by every
|
|
2945
|
+
* project that declares the source, so a project that declares another `--publisher` is
|
|
2946
|
+
* re-labelled here, at read time, and never changes what the others see (p1822).
|
|
2947
|
+
*/
|
|
2948
|
+
scopeLibraryIndex(libraries, defs) {
|
|
2949
|
+
const hidden = this.undeclaredSourceClones(libraries);
|
|
2950
|
+
const declared = this.declaredSourceEntries();
|
|
2951
|
+
const relabel = /* @__PURE__ */ new Map();
|
|
2952
|
+
for (const l of libraries) {
|
|
2953
|
+
const key = this.sourceCloneKey(l);
|
|
2954
|
+
const entry = key === void 0 ? void 0 : declared?.get(key);
|
|
2955
|
+
if (!entry?.publisher || hidden.has(l.id) || !("url" in l.backendConfig)) continue;
|
|
2956
|
+
const indexed = resolveSourcePublisher(l.path, l.backendConfig.publisher);
|
|
2957
|
+
const mine = resolveSourcePublisher(l.path, entry.publisher);
|
|
2958
|
+
if (indexed && mine && indexed !== mine) relabel.set(l.id, { from: indexed, to: mine });
|
|
2959
|
+
}
|
|
2960
|
+
if (hidden.size === 0 && relabel.size === 0) return { libraries, defs };
|
|
2961
|
+
const bare = (publisher) => publisher.replace(/^@/, "");
|
|
2962
|
+
return {
|
|
2963
|
+
libraries: libraries.filter((l) => !hidden.has(l.id)).map((l) => {
|
|
2964
|
+
const r = relabel.get(l.id);
|
|
2965
|
+
return r && "url" in l.backendConfig ? { ...l, backendConfig: { ...l.backendConfig, publisher: r.to } } : l;
|
|
2966
|
+
}),
|
|
2967
|
+
defs: defs.filter((d) => !d.libraryId || !hidden.has(d.libraryId)).map((d) => {
|
|
2968
|
+
const r = d.libraryId ? relabel.get(d.libraryId) : void 0;
|
|
2969
|
+
if (!r || bare(d.publisher) !== r.from) return d;
|
|
2970
|
+
return {
|
|
2971
|
+
...d,
|
|
2972
|
+
publisher: d.publisher.startsWith("@") ? `@${r.to}` : r.to,
|
|
2973
|
+
id: d.id.replace(`@${r.from}/`, `@${r.to}/`)
|
|
2974
|
+
};
|
|
2975
|
+
})
|
|
2976
|
+
};
|
|
2977
|
+
}
|
|
2881
2978
|
/**
|
|
2882
2979
|
* Library-origin lock entries for the assets {@link resolveLibraryEntries}
|
|
2883
2980
|
* matched. The locked version is the one actually deployed: the on-disk
|
|
@@ -2952,6 +3049,106 @@ var AssetManager = class {
|
|
|
2952
3049
|
})
|
|
2953
3050
|
);
|
|
2954
3051
|
}
|
|
3052
|
+
/**
|
|
3053
|
+
* The entries a deploy would write into some target harness: those without a current deployed
|
|
3054
|
+
* copy. An intact copy stays as it is, so a library change that does not reach it (a symlink
|
|
3055
|
+
* added next to the files) stops no `install` or `update` (p1857).
|
|
3056
|
+
*/
|
|
3057
|
+
needingDeploy(entries, link = false) {
|
|
3058
|
+
const targets = this.targetHarnesses();
|
|
3059
|
+
return entries.filter(
|
|
3060
|
+
(e) => targets.some((t) => entriesNeedingDeploy([e], this.deployOptsFor(t, link)).length > 0)
|
|
3061
|
+
);
|
|
3062
|
+
}
|
|
3063
|
+
/**
|
|
3064
|
+
* The files of a library asset that git has not committed (edited, new or staged only), as
|
|
3065
|
+
* paths relative to the library root. The asset's own folder, or its one manifest file when it
|
|
3066
|
+
* shares the folder with other assets. Empty when the asset is not in a git work tree.
|
|
3067
|
+
*/
|
|
3068
|
+
uncommittedAssetFiles(entry, libPath) {
|
|
3069
|
+
const provider = this.registry.getProvider(entry.kind);
|
|
3070
|
+
if (!provider) return [];
|
|
3071
|
+
let scope;
|
|
3072
|
+
try {
|
|
3073
|
+
const manifest = statSync(entry.source).isDirectory() ? readdirSync(entry.source).find((f) => provider.matchesPath(f)) : entry.source;
|
|
3074
|
+
if (!manifest) return [];
|
|
3075
|
+
const manifestPath = isAbsolute(manifest) ? manifest : join(entry.source, manifest);
|
|
3076
|
+
const filter = provider.defaultFileFilter(manifestPath);
|
|
3077
|
+
const rootName = relative(dirname(filter.assetRoot), filter.assetRoot);
|
|
3078
|
+
scope = filter.files.length > 1 || rootName === entry.name ? filter.assetRoot : manifestPath;
|
|
3079
|
+
} catch {
|
|
3080
|
+
return [];
|
|
3081
|
+
}
|
|
3082
|
+
const cwd = statSync(scope).isDirectory() ? scope : dirname(scope);
|
|
3083
|
+
const top = spawnSync("git", ["-C", cwd, "rev-parse", "--show-toplevel"], {
|
|
3084
|
+
encoding: "utf8"
|
|
3085
|
+
});
|
|
3086
|
+
if (top.status !== 0) return [];
|
|
3087
|
+
const status = spawnSync(
|
|
3088
|
+
"git",
|
|
3089
|
+
["-C", cwd, "status", "--porcelain", "--untracked-files=all", "--", scope],
|
|
3090
|
+
{ encoding: "utf8" }
|
|
3091
|
+
);
|
|
3092
|
+
if (status.status !== 0) return [];
|
|
3093
|
+
const root = top.stdout.trim();
|
|
3094
|
+
return status.stdout.split("\n").filter((l) => l.trim() !== "").map(
|
|
3095
|
+
(l) => relative(realpathSync(libPath), join(root, l.slice(3).trim().replace(/^"|"$/g, "")))
|
|
3096
|
+
);
|
|
3097
|
+
}
|
|
3098
|
+
/**
|
|
3099
|
+
* Warn when a library with a git remote has uncommitted changes in the folders of the assets
|
|
3100
|
+
* `add` or `install` lock: the lock records the bytes on this disk, which no clone of the
|
|
3101
|
+
* remote holds, so a teammate (or CI) cannot restore them. One line per library naming the
|
|
3102
|
+
* files; the command goes on (OQ5, p1859).
|
|
3103
|
+
*/
|
|
3104
|
+
async warnUncommittedLibraryAssets(lib) {
|
|
3105
|
+
if (lib.entries.length === 0) return;
|
|
3106
|
+
const snap = await this.loadLibraryIndex();
|
|
3107
|
+
const files = /* @__PURE__ */ new Map();
|
|
3108
|
+
for (const e of lib.entries) {
|
|
3109
|
+
const name = lib.libraryOf.get(e);
|
|
3110
|
+
const registered = name ? snap?.libraries.find((l) => l.name === name) : void 0;
|
|
3111
|
+
if (!name || !registered || !libraryRemoteUrl(registered)) continue;
|
|
3112
|
+
const libPath = this.libraryPath({ name }, snap);
|
|
3113
|
+
if (!libPath) continue;
|
|
3114
|
+
const set = files.get(name) ?? /* @__PURE__ */ new Set();
|
|
3115
|
+
for (const f of this.uncommittedAssetFiles(e, libPath)) set.add(f);
|
|
3116
|
+
if (set.size > 0) files.set(name, set);
|
|
3117
|
+
}
|
|
3118
|
+
for (const [name, set] of files) {
|
|
3119
|
+
const list = [...set].sort();
|
|
3120
|
+
const shown = list.slice(0, 5).join(", ");
|
|
3121
|
+
const more = list.length > 5 ? `, +${list.length - 5} more` : "";
|
|
3122
|
+
this.emitLibraryCollision(
|
|
3123
|
+
`library "${name}" has uncommitted changes (${shown}${more}): other machines cannot restore those bytes from its remote. Commit and push them.`,
|
|
3124
|
+
[]
|
|
3125
|
+
);
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
/**
|
|
3129
|
+
* Whether every declared ref is locked and no declared pin differs from the locked version:
|
|
3130
|
+
* `skaile.yaml` asks for nothing the lock does not hold. A declared preset counts when the
|
|
3131
|
+
* lock records it.
|
|
3132
|
+
*/
|
|
3133
|
+
declaredMatchesLock(lock, declared) {
|
|
3134
|
+
const keys = Object.keys(lock.assets).map((key) => parseCanonicalLockKey(key));
|
|
3135
|
+
for (const d of declared) {
|
|
3136
|
+
const want = parseRefTolerant(d.split(" ")[0] ?? d);
|
|
3137
|
+
if (!want) return false;
|
|
3138
|
+
if (want.kind === "preset") {
|
|
3139
|
+
if (!this.presetRecorded(want)) return false;
|
|
3140
|
+
continue;
|
|
3141
|
+
}
|
|
3142
|
+
const held = keys.filter(
|
|
3143
|
+
(id) => id.kind === want.kind && id.name === want.name && (!want.publisher || !id.publisher || id.publisher === want.publisher)
|
|
3144
|
+
);
|
|
3145
|
+
if (held.length === 0) return false;
|
|
3146
|
+
if (want.pin && !held.some((id) => !id.version || matchPin(want.pin, id.version))) {
|
|
3147
|
+
return false;
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
return true;
|
|
3151
|
+
}
|
|
2955
3152
|
/**
|
|
2956
3153
|
* Lock keys that `skaile.yaml` still wants: the entries a declared ref names, plus every
|
|
2957
3154
|
* entry such an asset requires, transitively. All keys when a `preset:` is declared.
|
|
@@ -2985,7 +3182,12 @@ var AssetManager = class {
|
|
|
2985
3182
|
* assets on this machine (not registered, or registered with its directory gone). Plain
|
|
2986
3183
|
* `install` stops on a non-empty list, the same lines `install --locked` prints: it must
|
|
2987
3184
|
* not re-resolve a locked asset from another origin. The ONE function that decides "the
|
|
2988
|
-
* locked library is not here", so a
|
|
3185
|
+
* locked library is not here", so a store-restore fallback extends it in one place.
|
|
3186
|
+
*
|
|
3187
|
+
* An entry `install --locked` already restored from a store (its library is not registered
|
|
3188
|
+
* here and the store cache holds the locked version, see {@link restoredFromStoreCache}) is no
|
|
3189
|
+
* line: it is returned in `restored`, and plain `install` then restores the lock as
|
|
3190
|
+
* `install --locked` does instead of re-resolving it from another origin (OQ8, p1655).
|
|
2989
3191
|
*
|
|
2990
3192
|
* Only entries `skaile.yaml` still declares, or that a declared asset requires
|
|
2991
3193
|
* (transitively, read from the deployed copy), count. A stale entry nothing declares is
|
|
@@ -3000,21 +3202,26 @@ var AssetManager = class {
|
|
|
3000
3202
|
const locked = Object.entries(lock.assets).filter(
|
|
3001
3203
|
([key, e]) => e.library !== void 0 && !e.library.installed && inScope.has(key)
|
|
3002
3204
|
);
|
|
3003
|
-
if (locked.length === 0) return [];
|
|
3004
|
-
const snap = await this.loadLibraryIndex();
|
|
3005
3205
|
const lines = [];
|
|
3206
|
+
const restored = [];
|
|
3207
|
+
if (locked.length === 0) return { lines, restored };
|
|
3208
|
+
const snap = await this.loadLibraryIndex();
|
|
3006
3209
|
for (const [ref, e] of locked) {
|
|
3007
3210
|
const { publisher, kind, name } = parseCanonicalLockKey(ref);
|
|
3008
3211
|
if (!publisher || !kind || !name) continue;
|
|
3009
3212
|
const lookup = this.lockedLibrary(e.library, snap, { kind, publisher, name });
|
|
3010
3213
|
if (lookup.state === "ok") continue;
|
|
3214
|
+
if (await this.restoredFromStoreCache(ref, e, snap)) {
|
|
3215
|
+
restored.push(ref);
|
|
3216
|
+
continue;
|
|
3217
|
+
}
|
|
3011
3218
|
const component = this.installTarget(kind);
|
|
3012
3219
|
const deployed = component !== void 0 && isDeployed(component, name, this.harness, this.global, this.projectDir);
|
|
3013
3220
|
const problem = lockedLibraryProblem(lookup, e.library, `${kind}:@${publisher}/${name}`);
|
|
3014
3221
|
const kept = deployed ? "the deployed copy and its lock entry are kept" : "its lock entry is kept; no deployed copy exists";
|
|
3015
3222
|
lines.push(`${ref} (${problem}; ${kept})`);
|
|
3016
3223
|
}
|
|
3017
|
-
return lines;
|
|
3224
|
+
return { lines, restored };
|
|
3018
3225
|
}
|
|
3019
3226
|
/**
|
|
3020
3227
|
* Re-resolve every library-origin lock entry from its named library, for
|
|
@@ -3023,17 +3230,21 @@ var AssetManager = class {
|
|
|
3023
3230
|
* version; anything else is reported in `missing` with the reason.
|
|
3024
3231
|
*
|
|
3025
3232
|
* @param opts.storeFallback - `install --locked` only: an entry whose library is not registered
|
|
3026
|
-
* here is restored from a store that serves the locked sha256 (OQ15, p1490).
|
|
3027
|
-
* the
|
|
3233
|
+
* here is restored from a store that serves the locked sha256 (OQ8, OQ15, p1490, p1655). The
|
|
3234
|
+
* lock records the library's remote and hash but no commit and no file list, so the library
|
|
3235
|
+
* remote itself cannot be fetched at a locked commit; the store pointer names the upstream
|
|
3236
|
+
* repository and commit that hold exactly the hashed bytes. Reads such as the drift check
|
|
3237
|
+
* never ask a store.
|
|
3028
3238
|
*/
|
|
3029
3239
|
async restoreLibraryLockEntries(lock, opts) {
|
|
3030
3240
|
const entries = [];
|
|
3031
3241
|
const missing = [];
|
|
3032
3242
|
const viaStore = [];
|
|
3243
|
+
const storeOrigins = {};
|
|
3033
3244
|
const locked = Object.entries(lock.assets).filter(
|
|
3034
3245
|
([, e]) => e.library !== void 0 && !e.library.installed
|
|
3035
3246
|
);
|
|
3036
|
-
if (locked.length === 0) return { entries, missing, viaStore };
|
|
3247
|
+
if (locked.length === 0) return { entries, missing, viaStore, storeOrigins };
|
|
3037
3248
|
const snap = await this.loadLibraryIndex();
|
|
3038
3249
|
const diskHashes = /* @__PURE__ */ new Map();
|
|
3039
3250
|
const fileSets = /* @__PURE__ */ new Map();
|
|
@@ -3048,8 +3259,9 @@ var AssetManager = class {
|
|
|
3048
3259
|
if (lookup.state !== "ok") {
|
|
3049
3260
|
const fallback = lookup.state === "unregistered" && opts?.storeFallback ? await this.storeEntryForLockedLibraryAsset(publisher, kind, name, origin) : null;
|
|
3050
3261
|
if (fallback) {
|
|
3051
|
-
entries.push(fallback);
|
|
3262
|
+
entries.push(fallback.entry);
|
|
3052
3263
|
viaStore.push(ref);
|
|
3264
|
+
storeOrigins[ref] = fallback.from;
|
|
3053
3265
|
continue;
|
|
3054
3266
|
}
|
|
3055
3267
|
missing.push(
|
|
@@ -3086,7 +3298,7 @@ var AssetManager = class {
|
|
|
3086
3298
|
const onDisk = libraryDiskHashes(libPath, diskHashes, this.registry).get(`${kind}:${name}`);
|
|
3087
3299
|
if (onDisk !== void 0 && onDisk !== origin.sha256) {
|
|
3088
3300
|
missing.push(
|
|
3089
|
-
`${ref} (library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; re-lock with \`skaile
|
|
3301
|
+
`${ref} (library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; re-lock with \`skaile update\`)`
|
|
3090
3302
|
);
|
|
3091
3303
|
continue;
|
|
3092
3304
|
}
|
|
@@ -3094,17 +3306,21 @@ var AssetManager = class {
|
|
|
3094
3306
|
found.version = sameVersion ? origin.version : current;
|
|
3095
3307
|
entries.push(withLibraryFiles(found, libPath, fileSets, this.registry));
|
|
3096
3308
|
}
|
|
3097
|
-
return { entries, missing, viaStore };
|
|
3309
|
+
return { entries, missing, viaStore, storeOrigins };
|
|
3098
3310
|
}
|
|
3099
3311
|
/**
|
|
3100
|
-
* Whether a library-origin lock entry was restored from
|
|
3312
|
+
* Whether a library-origin lock entry was restored from a store: its library is not
|
|
3101
3313
|
* registered here, and the project's store cache holds the locked version (`install --locked`
|
|
3102
|
-
* fetched and SHA-verified
|
|
3103
|
-
* as restorable as a source- or store-origin one: `check
|
|
3104
|
-
* from the deployed copy and do not ask for the library (OQ8,
|
|
3105
|
-
* that never restored anything here stays a gap.
|
|
3314
|
+
* fetched it there and SHA-verified every file against the sha256 the lock recorded). Such an
|
|
3315
|
+
* entry is as restorable as a source- or store-origin one: `check`, `doctor` and plain
|
|
3316
|
+
* `install` read its requirements from the deployed copy and do not ask for the library (OQ8,
|
|
3317
|
+
* p1655). An unregistered library that never restored anything here stays a gap.
|
|
3318
|
+
*
|
|
3319
|
+
* This only checks that the cache directory of the locked version is not empty: the bytes were
|
|
3320
|
+
* verified when they were fetched, and a later edit of the deployed copy is the `modified`
|
|
3321
|
+
* drift check's job, not this one's.
|
|
3106
3322
|
*/
|
|
3107
|
-
async
|
|
3323
|
+
async restoredFromStoreCache(key, entry, snap) {
|
|
3108
3324
|
const origin = entry.library;
|
|
3109
3325
|
if (!origin || origin.installed || !origin.sha256 || !origin.version) return false;
|
|
3110
3326
|
if (isPseudoVersion(origin.version)) return false;
|
|
@@ -3124,7 +3340,8 @@ var AssetManager = class {
|
|
|
3124
3340
|
* store (project `stores:` or the global catalog) that serves `kind:@publisher/name#version`
|
|
3125
3341
|
* under the very sha256 the lock recorded holds the same bytes. The entry is fetched and
|
|
3126
3342
|
* verified like any store asset; the lock stays as it is. `null` when the lock has no hash,
|
|
3127
|
-
* no store answers, or the hash differs (OQ15, p1490).
|
|
3343
|
+
* no store answers, or the hash differs (OQ15, p1490). `from` names the store and the
|
|
3344
|
+
* upstream repository and commit its pointer gives, for the notice.
|
|
3128
3345
|
*/
|
|
3129
3346
|
async storeEntryForLockedLibraryAsset(publisher, kind, name, origin) {
|
|
3130
3347
|
if (!origin.sha256 || !origin.version || isPseudoVersion(origin.version)) return null;
|
|
@@ -3155,7 +3372,12 @@ var AssetManager = class {
|
|
|
3155
3372
|
],
|
|
3156
3373
|
repositories
|
|
3157
3374
|
);
|
|
3158
|
-
if (entry)
|
|
3375
|
+
if (entry) {
|
|
3376
|
+
return {
|
|
3377
|
+
entry,
|
|
3378
|
+
from: `${store.url} (${sourceShortName(m.sourceUrl)}@${m.commit.slice(0, 7)})`
|
|
3379
|
+
};
|
|
3380
|
+
}
|
|
3159
3381
|
} catch (err) {
|
|
3160
3382
|
this.noteStoreFailure(store.url, err);
|
|
3161
3383
|
}
|
|
@@ -3198,12 +3420,21 @@ var AssetManager = class {
|
|
|
3198
3420
|
async keepLockedLibraryEntries(lock) {
|
|
3199
3421
|
if (!lock) return void 0;
|
|
3200
3422
|
const out = /* @__PURE__ */ new Map();
|
|
3423
|
+
const snap = await this.loadLibraryIndex();
|
|
3424
|
+
const diskHashes = /* @__PURE__ */ new Map();
|
|
3201
3425
|
for (const [key, entry] of Object.entries(lock.assets)) {
|
|
3202
3426
|
if (!entry.library || entry.library.installed || !entry.library.version) continue;
|
|
3203
3427
|
const id = parseCanonicalLockKey(key);
|
|
3204
3428
|
if (!id.publisher || !id.kind || !id.name) continue;
|
|
3205
3429
|
const requires = entry.requires ?? await this.deployedRequirementsOf(id);
|
|
3206
|
-
|
|
3430
|
+
const lookup = this.lockedLibrary(entry.library, snap, {
|
|
3431
|
+
kind: id.kind,
|
|
3432
|
+
publisher: id.publisher,
|
|
3433
|
+
name: id.name
|
|
3434
|
+
});
|
|
3435
|
+
const onDisk = lookup.state === "ok" && entry.library.sha256 ? libraryDiskHashes(lookup.path, diskHashes, this.registry).get(`${id.kind}:${id.name}`) : void 0;
|
|
3436
|
+
const contentChanged = onDisk !== void 0 && onDisk !== entry.library.sha256;
|
|
3437
|
+
out.set(`${id.publisher}/${id.kind}:${id.name}`, { key, entry, requires, contentChanged });
|
|
3207
3438
|
}
|
|
3208
3439
|
return out.size > 0 ? out : void 0;
|
|
3209
3440
|
}
|
|
@@ -3514,6 +3745,7 @@ var AssetManager = class {
|
|
|
3514
3745
|
const requiredBy = /* @__PURE__ */ new Map();
|
|
3515
3746
|
const keptVersions = {};
|
|
3516
3747
|
const versionBlocked = [];
|
|
3748
|
+
const contentHeld = [];
|
|
3517
3749
|
const lib = { entries: [], resolved: /* @__PURE__ */ new Set(), libraryOf: /* @__PURE__ */ new Map() };
|
|
3518
3750
|
const missing = /* @__PURE__ */ new Set();
|
|
3519
3751
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -3528,6 +3760,9 @@ var AssetManager = class {
|
|
|
3528
3760
|
const locked = opts.keepLocked?.get(id);
|
|
3529
3761
|
const lockedVersion = locked?.entry.library?.version;
|
|
3530
3762
|
if (!locked || !lockedVersion || !e.version) return void 0;
|
|
3763
|
+
if (locked.contentChanged && coerceVersion(e.version) === coerceVersion(lockedVersion)) {
|
|
3764
|
+
return locked;
|
|
3765
|
+
}
|
|
3531
3766
|
if (isPseudoVersion(lockedVersion) || isPseudoVersion(e.version)) return void 0;
|
|
3532
3767
|
if (coerceVersion(e.version) === coerceVersion(lockedVersion)) return void 0;
|
|
3533
3768
|
for (const r of asked) if (refIdentity(r) === id && r.includes("#")) return void 0;
|
|
@@ -3564,10 +3799,18 @@ var AssetManager = class {
|
|
|
3564
3799
|
});
|
|
3565
3800
|
} else if (keep) {
|
|
3566
3801
|
keptVersions[keep.key] = keep.entry;
|
|
3802
|
+
const sameVersion = coerceVersion(e.version ?? "") === coerceVersion(keep.entry.library?.version ?? "");
|
|
3803
|
+
const libraryName = origin ?? keep.entry.library?.name ?? "";
|
|
3567
3804
|
if (!this.lockedCopyDeployed(e.kind, e.name)) {
|
|
3568
3805
|
versionBlocked.push(
|
|
3569
|
-
`${keep.key} (library "${origin ?? keep.entry.library?.name}" is at ${e.version}, locked ${keep.entry.library?.version}; the deployed copy is gone and cannot be restored from the ${gt(coerceVersion(e.version ?? ""), coerceVersion(keep.entry.library?.version ?? "")) ? "newer" : "older"} files \u2014 \`skaile update\` moves the lock to it)`
|
|
3806
|
+
sameVersion ? `${keep.key} (library "${libraryName}" content changed since lock; the deployed copy is gone and cannot be restored from the changed files \u2014 \`skaile update\` takes the change)` : `${keep.key} (library "${origin ?? keep.entry.library?.name}" is at ${e.version}, locked ${keep.entry.library?.version}; the deployed copy is gone and cannot be restored from the ${gt(coerceVersion(e.version ?? ""), coerceVersion(keep.entry.library?.version ?? "")) ? "newer" : "older"} files \u2014 \`skaile update\` moves the lock to it)`
|
|
3570
3807
|
);
|
|
3808
|
+
} else if (sameVersion) {
|
|
3809
|
+
contentHeld.push({
|
|
3810
|
+
ref: keep.key,
|
|
3811
|
+
library: libraryName,
|
|
3812
|
+
version: keep.entry.library?.version ?? ""
|
|
3813
|
+
});
|
|
3571
3814
|
}
|
|
3572
3815
|
} else {
|
|
3573
3816
|
lib.entries.push(e);
|
|
@@ -3670,7 +3913,8 @@ var AssetManager = class {
|
|
|
3670
3913
|
presets,
|
|
3671
3914
|
requiredBy,
|
|
3672
3915
|
keptVersions,
|
|
3673
|
-
versionBlocked
|
|
3916
|
+
versionBlocked,
|
|
3917
|
+
contentHeld
|
|
3674
3918
|
};
|
|
3675
3919
|
}
|
|
3676
3920
|
/**
|
|
@@ -3942,18 +4186,25 @@ var AssetManager = class {
|
|
|
3942
4186
|
return this.installLocked(repositories, patches, dependencies);
|
|
3943
4187
|
}
|
|
3944
4188
|
const lockForLibraries = this.tryReadLock();
|
|
4189
|
+
const restoredFromStore = /* @__PURE__ */ new Set();
|
|
3945
4190
|
if (lockForLibraries) {
|
|
3946
4191
|
const unavailable = await this.unavailableLockedLibraries(lockForLibraries, dependencies);
|
|
3947
|
-
|
|
4192
|
+
for (const key of unavailable.restored) restoredFromStore.add(key);
|
|
4193
|
+
if (unavailable.lines.length > 0) {
|
|
3948
4194
|
return {
|
|
3949
4195
|
deployed: [],
|
|
3950
4196
|
removed: [],
|
|
3951
|
-
missing: unavailable,
|
|
4197
|
+
missing: unavailable.lines,
|
|
3952
4198
|
lockWritten: false,
|
|
3953
4199
|
npmInstalled: [],
|
|
3954
4200
|
npmFailed: []
|
|
3955
4201
|
};
|
|
3956
4202
|
}
|
|
4203
|
+
if (unavailable.restored.length > 0 && this.declaredMatchesLock(lockForLibraries, dependencies) && [...await this.declaredLockKeys(lockForLibraries, dependencies)].every(
|
|
4204
|
+
(key) => restoredFromStore.has(key)
|
|
4205
|
+
)) {
|
|
4206
|
+
return this.installLocked(repositories, patches, dependencies);
|
|
4207
|
+
}
|
|
3957
4208
|
const orphans = await this.orphanedSourceGaps(
|
|
3958
4209
|
await this.declaredLockKeys(lockForLibraries, dependencies),
|
|
3959
4210
|
true
|
|
@@ -3989,7 +4240,8 @@ var AssetManager = class {
|
|
|
3989
4240
|
presets,
|
|
3990
4241
|
requiredBy,
|
|
3991
4242
|
keptVersions,
|
|
3992
|
-
versionBlocked
|
|
4243
|
+
versionBlocked,
|
|
4244
|
+
contentHeld
|
|
3993
4245
|
} = await this.resolveLibraryFirst(dependencies, {
|
|
3994
4246
|
provenanceIndex,
|
|
3995
4247
|
overrides,
|
|
@@ -4057,6 +4309,7 @@ var AssetManager = class {
|
|
|
4057
4309
|
missingHints[ref] = `${fix ? "" : missingHints[ref] ?? ""} (${notes.join("; ")})`;
|
|
4058
4310
|
}
|
|
4059
4311
|
const directLock = this.directInstallLockEntries();
|
|
4312
|
+
await this.warnUncommittedLibraryAssets(lib);
|
|
4060
4313
|
const libraryLock = {
|
|
4061
4314
|
...directLock,
|
|
4062
4315
|
...await this.libraryLockEntries(lib, opts?.moveLibraries === true),
|
|
@@ -4069,7 +4322,33 @@ var AssetManager = class {
|
|
|
4069
4322
|
await this.keepRequiredByKept(prevLock, kept, Object.keys(freshLock.assets));
|
|
4070
4323
|
const entries = [...await this.buildCatalogEntries(resolved, repositories), ...lib.entries];
|
|
4071
4324
|
assertFlowsLoad(entries, "installed");
|
|
4072
|
-
assertNoLibrarySymlinks(
|
|
4325
|
+
assertNoLibrarySymlinks(
|
|
4326
|
+
this.needingDeploy(entries, opts?.link === true),
|
|
4327
|
+
this.registry,
|
|
4328
|
+
repositories,
|
|
4329
|
+
opts?.link === true
|
|
4330
|
+
);
|
|
4331
|
+
if (libraryAssetCheck && lib.entries.length > 0) {
|
|
4332
|
+
const lockedIds = new Set([...lockedKeys].map((k) => k.split("#")[0]));
|
|
4333
|
+
const snap = await this.loadLibraryIndex();
|
|
4334
|
+
for (const e of lib.entries) {
|
|
4335
|
+
if (lockedIds.has(canonicalEntryRef(e).split("#")[0])) continue;
|
|
4336
|
+
const origin = lib.libraryOf.get(e);
|
|
4337
|
+
const libPath = origin ? this.libraryPath({ name: origin }, snap) : null;
|
|
4338
|
+
if (!origin || !libPath || !e.source) continue;
|
|
4339
|
+
const lines = libraryAssetCheck(
|
|
4340
|
+
{ kind: e.kind, name: e.name, source: e.source },
|
|
4341
|
+
libPath
|
|
4342
|
+
).filter((l) => /placeholder/i.test(l));
|
|
4343
|
+
if (lines.length > 0) {
|
|
4344
|
+
throw new Error(
|
|
4345
|
+
`${canonicalEntryRef(e)} in library "${origin}" fails the checks of \`skaile validate\` - nothing was installed:
|
|
4346
|
+
${lines.map((l) => ` ${l}`).join("\n")}
|
|
4347
|
+
Fix the asset, then run \`skaile library index ${origin}\` and install again.`
|
|
4348
|
+
);
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
}
|
|
4073
4352
|
const forceCommand = opts?.moveLibraries === true ? "skaile update --force" : "skaile install --force";
|
|
4074
4353
|
if (!opts?.force) {
|
|
4075
4354
|
await this.assertNoHandEditsPruned(
|
|
@@ -4128,6 +4407,8 @@ var AssetManager = class {
|
|
|
4128
4407
|
...mcpRestored
|
|
4129
4408
|
];
|
|
4130
4409
|
const rewritten = this.rewrittenAgentFiles(unrecordedAgents);
|
|
4410
|
+
const editedHeld = new Set(copyDrift.filter((d) => d.libraryChanged).map((d) => d.ref));
|
|
4411
|
+
const heldEdits = editedHeld.size > 0 && opts?.moveLibraries !== true ? (await this.projectState()).gaps.filter((g) => g.type === "modified" && editedHeld.has(g.ref)).map((g) => g.message) : [];
|
|
4131
4412
|
const lockWanted = resolved.length > 0 || lib.entries.length > 0 || existsSync(this.lockPath);
|
|
4132
4413
|
let lockWritten = false;
|
|
4133
4414
|
let relocked = [];
|
|
@@ -4147,8 +4428,15 @@ var AssetManager = class {
|
|
|
4147
4428
|
}
|
|
4148
4429
|
this.recordInstallHistory(deployed, removed);
|
|
4149
4430
|
const { npmInstalled, npmFailed } = await this.installRuntimeAssetDeps();
|
|
4150
|
-
const
|
|
4431
|
+
const restoredRefs = stillMissing.filter((m) => {
|
|
4432
|
+
const keys = kept.keysByRef.get(m) ?? [];
|
|
4433
|
+
return keys.length > 0 && keys.every((k) => restoredFromStore.has(k));
|
|
4434
|
+
});
|
|
4435
|
+
const reportedMissing = stillMissing.filter(
|
|
4436
|
+
(m) => !storeNotChecked.some((n) => n.ref === m) && !restoredRefs.includes(m)
|
|
4437
|
+
);
|
|
4151
4438
|
for (const n of storeNotChecked) delete missingHints[n.ref];
|
|
4439
|
+
for (const m of restoredRefs) delete missingHints[m];
|
|
4152
4440
|
await this.adviseMissing(reportedMissing, missingHints);
|
|
4153
4441
|
const placeholderBodies = scaffoldBodyRefs(lib.entries, deployed);
|
|
4154
4442
|
const placeholderDescriptions = scaffoldDescriptionRefs(lib.entries, deployed);
|
|
@@ -4158,13 +4446,15 @@ var AssetManager = class {
|
|
|
4158
4446
|
missing: [
|
|
4159
4447
|
...reportedMissing,
|
|
4160
4448
|
...versionBlocked.filter((b) => !reportedMissing.includes(b)),
|
|
4161
|
-
...composedDrift
|
|
4449
|
+
...composedDrift,
|
|
4450
|
+
...heldEdits.filter((h) => !reportedMissing.includes(h))
|
|
4162
4451
|
],
|
|
4163
4452
|
...placeholderBodies.length > 0 ? { placeholderBodies } : {},
|
|
4164
4453
|
...placeholderDescriptions.length > 0 ? { placeholderDescriptions } : {},
|
|
4165
4454
|
...storeNotChecked.length > 0 ? { storeNotChecked } : {},
|
|
4166
4455
|
...Object.keys(missingHints).length > 0 ? { missingHints } : {},
|
|
4167
4456
|
...relocked.length > 0 ? { relocked } : {},
|
|
4457
|
+
...contentHeld.length > 0 ? { contentHeld } : {},
|
|
4168
4458
|
...inferredHarnesses.length > 0 ? { inferredHarnesses } : {},
|
|
4169
4459
|
...moved.length > 0 ? { moved } : {},
|
|
4170
4460
|
...replaced.length > 0 ? { replaced } : {},
|
|
@@ -4564,7 +4854,11 @@ Nothing was changed. Move your edits away, or run \`${forceCommand}\` to overwri
|
|
|
4564
4854
|
).split(sep).join("/");
|
|
4565
4855
|
files = files.map((f) => `${dir}/${f}`);
|
|
4566
4856
|
}
|
|
4567
|
-
if (files.length > 0)
|
|
4857
|
+
if (files.length > 0) {
|
|
4858
|
+
lines.push(
|
|
4859
|
+
d.unrecorded ? `${d.ref} (${files.join(", ")} differs from the library's content now; the lock keeps no per-file record, so it may be a library change, not your edit)` : `${d.ref} (${files.join(", ")} was edited)`
|
|
4860
|
+
);
|
|
4861
|
+
}
|
|
4568
4862
|
}
|
|
4569
4863
|
if (lines.length === 0) return;
|
|
4570
4864
|
throw new Error(
|
|
@@ -4632,11 +4926,15 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
4632
4926
|
});
|
|
4633
4927
|
}
|
|
4634
4928
|
}
|
|
4635
|
-
/**
|
|
4929
|
+
/**
|
|
4930
|
+
* Read the lock, returning null on a legacy v1 lock instead of throwing. A lock that is not
|
|
4931
|
+
* valid YAML throws {@link LockParseError}: it is not an empty lock (p1892).
|
|
4932
|
+
*/
|
|
4636
4933
|
tryReadLock() {
|
|
4637
4934
|
try {
|
|
4638
4935
|
return readLock(this.lockPath);
|
|
4639
|
-
} catch {
|
|
4936
|
+
} catch (err) {
|
|
4937
|
+
if (err instanceof LockParseError) throw err;
|
|
4640
4938
|
return null;
|
|
4641
4939
|
}
|
|
4642
4940
|
}
|
|
@@ -4806,13 +5104,11 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
4806
5104
|
);
|
|
4807
5105
|
}
|
|
4808
5106
|
const declBySlug = new Map(Object.entries(repositories));
|
|
4809
|
-
const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
|
|
4810
5107
|
const factoryDecl = Object.values(repositories).find((d) => d.factory);
|
|
4811
5108
|
const factoryDir = factoryDecl?.path ?? null;
|
|
4812
|
-
const isFactoryUrl = (url) => factoryDir !== null && normalizeRepoUrl(url) === factoryUrl;
|
|
4813
5109
|
const unavailable = [];
|
|
4814
5110
|
for (const src of lock.sources) {
|
|
4815
|
-
if (
|
|
5111
|
+
if (factoryDir !== null && isFactoryMemorySource(src)) continue;
|
|
4816
5112
|
const slug = sourceCacheKey(src.url);
|
|
4817
5113
|
const declared = declBySlug.get(slug);
|
|
4818
5114
|
if (!declared && GITHUB_REPO_URL.test(src.url)) continue;
|
|
@@ -4842,8 +5138,8 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
4842
5138
|
cloneOrigin[key] = entry;
|
|
4843
5139
|
}
|
|
4844
5140
|
}
|
|
4845
|
-
const verification = verifyLock({ ...lock, assets: cloneOrigin }, (sourceUrl) => {
|
|
4846
|
-
if (
|
|
5141
|
+
const verification = verifyLock({ ...lock, assets: cloneOrigin }, (sourceUrl, entry) => {
|
|
5142
|
+
if (factoryDir !== null && isFactoryMemorySource(entry.source)) return factoryDir;
|
|
4847
5143
|
const slug = sourceCacheKey(sourceUrl);
|
|
4848
5144
|
return this.resolveRepoDir(repositories[slug] ?? { url: sourceUrl }, slug);
|
|
4849
5145
|
});
|
|
@@ -4875,7 +5171,11 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
4875
5171
|
}
|
|
4876
5172
|
const library = await this.restoreLibraryLockEntries(lock, { storeFallback: true });
|
|
4877
5173
|
assertFlowsLoad([...resolved, ...library.entries], "installed");
|
|
4878
|
-
assertNoLibrarySymlinks(
|
|
5174
|
+
assertNoLibrarySymlinks(
|
|
5175
|
+
this.needingDeploy([...resolved, ...library.entries]),
|
|
5176
|
+
this.registry,
|
|
5177
|
+
repositories
|
|
5178
|
+
);
|
|
4879
5179
|
const inferredHarnesses = this.inferLegacyHarnessSubsets([...resolved, ...library.entries]);
|
|
4880
5180
|
const composedPre = /* @__PURE__ */ new Set();
|
|
4881
5181
|
if (!this.global) {
|
|
@@ -4939,7 +5239,12 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
4939
5239
|
const p = parseRefTolerant(g.ref);
|
|
4940
5240
|
return !(p && alreadyMissing.has(`${p.kind}:${p.name}`));
|
|
4941
5241
|
}).map((g) => g.message);
|
|
4942
|
-
const libraryNotices = this.
|
|
5242
|
+
const libraryNotices = this.storeRestoreNotices(
|
|
5243
|
+
lock,
|
|
5244
|
+
library.viaStore,
|
|
5245
|
+
library.storeOrigins,
|
|
5246
|
+
deployed.length > 0 || restored.length > 0
|
|
5247
|
+
);
|
|
4943
5248
|
const placeholderBodies = scaffoldBodyRefs(library.entries, deployed);
|
|
4944
5249
|
const placeholderDescriptions = scaffoldDescriptionRefs(library.entries, deployed);
|
|
4945
5250
|
return {
|
|
@@ -4958,22 +5263,44 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
4958
5263
|
}
|
|
4959
5264
|
/**
|
|
4960
5265
|
* One notice line per locked library that is not registered here and whose assets
|
|
4961
|
-
* `install --locked` restored from
|
|
4962
|
-
*
|
|
5266
|
+
* `install --locked` restored from a store: names the library, how many assets came from
|
|
5267
|
+
* which store (and the upstream repository and commit its pointer names), and how to register
|
|
5268
|
+
* the library to move the lock later (OQ8, p1655). Every file was SHA-verified against the
|
|
5269
|
+
* hash the lock recorded.
|
|
4963
5270
|
*/
|
|
4964
|
-
|
|
5271
|
+
storeRestoreNotices(lock, viaStore, storeOrigins, wroteFiles) {
|
|
4965
5272
|
const byLibrary = /* @__PURE__ */ new Map();
|
|
4966
5273
|
for (const key of viaStore) {
|
|
4967
5274
|
const origin = lock.assets[key]?.library;
|
|
4968
5275
|
if (!origin) continue;
|
|
4969
5276
|
const name = unregisteredLibraryName(origin);
|
|
4970
|
-
const row = byLibrary.get(name) ?? {
|
|
5277
|
+
const row = byLibrary.get(name) ?? {
|
|
5278
|
+
...origin.url ? { url: origin.url } : {},
|
|
5279
|
+
refs: [],
|
|
5280
|
+
from: /* @__PURE__ */ new Set()
|
|
5281
|
+
};
|
|
4971
5282
|
row.refs.push(key);
|
|
5283
|
+
const from = storeOrigins[key];
|
|
5284
|
+
if (from) row.from.add(from);
|
|
4972
5285
|
byLibrary.set(name, row);
|
|
4973
5286
|
}
|
|
4974
|
-
return [...byLibrary].map(([name, { url, refs }]) => {
|
|
5287
|
+
return [...byLibrary].map(([name, { url, refs, from }]) => {
|
|
4975
5288
|
const register = url ? `skaile library init ${name} --git ${url}` : `skaile library init ${name} --path <dir>`;
|
|
4976
|
-
|
|
5289
|
+
if (!wroteFiles) {
|
|
5290
|
+
return `Library "${name}" is not registered here. Register it with \`${register}\` to move the lock later.`;
|
|
5291
|
+
}
|
|
5292
|
+
const byStore = /* @__PURE__ */ new Map();
|
|
5293
|
+
for (const f of from) {
|
|
5294
|
+
const storeUrl = f.split(" (")[0] ?? f;
|
|
5295
|
+
const pointers = byStore.get(storeUrl) ?? /* @__PURE__ */ new Set();
|
|
5296
|
+
pointers.add(f);
|
|
5297
|
+
byStore.set(storeUrl, pointers);
|
|
5298
|
+
}
|
|
5299
|
+
const stores = [...byStore].map(
|
|
5300
|
+
([storeUrl, pointers]) => pointers.size === 1 ? [...pointers][0] : storeUrl
|
|
5301
|
+
);
|
|
5302
|
+
const where = stores.length > 0 ? ` from the store ${stores.join(", ")}` : " from a store";
|
|
5303
|
+
return `Library "${name}" is not registered here: restored ${refs.length} asset${refs.length === 1 ? "" : "s"}${where}, every file checked against the lock. Register it with \`${register}\` to move the lock later.`;
|
|
4977
5304
|
});
|
|
4978
5305
|
}
|
|
4979
5306
|
/**
|
|
@@ -5057,7 +5384,6 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
5057
5384
|
*/
|
|
5058
5385
|
planAddItems(resolved, lib, stores, parsed) {
|
|
5059
5386
|
const storeUrls = new Set(stores.map((s) => normalizeRepoUrl(s.url)));
|
|
5060
|
-
const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
|
|
5061
5387
|
const shownPath = (dir) => {
|
|
5062
5388
|
const rel = relative(this.projectDir, dir);
|
|
5063
5389
|
return this.global || rel.startsWith("..") ? dir.replace(homedir(), "~") : `${rel}${dir.endsWith(sep) ? sep : ""}`;
|
|
@@ -5090,7 +5416,7 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
5090
5416
|
publisher: c.publisher.replace(/^@/, "")
|
|
5091
5417
|
}),
|
|
5092
5418
|
version: c.version,
|
|
5093
|
-
origin: storeUrls.has(url) ? `store ${c.sourceUrl}` : url
|
|
5419
|
+
origin: storeUrls.has(url) ? `store ${c.sourceUrl}` : isFactoryMemorySource({ url: c.sourceUrl, commit: c.commit }) ? "factory" : `source ${sourceShortName(c.sourceUrl)}`,
|
|
5094
5420
|
requested: asked(c.kind, c.name, c.publisher),
|
|
5095
5421
|
...planPaths(
|
|
5096
5422
|
folders(c.kind, c.name),
|
|
@@ -5266,6 +5592,30 @@ Nothing was changed. Copy your edits away, or run \`${forceCommand}\` to replace
|
|
|
5266
5592
|
}
|
|
5267
5593
|
}
|
|
5268
5594
|
}
|
|
5595
|
+
if (libraryAssetCheck) {
|
|
5596
|
+
for (const l of snap?.libraries ?? []) {
|
|
5597
|
+
const libPath = this.libraryPath({ name: l.name }, snap);
|
|
5598
|
+
const manifest = libPath ? loadSkPublishManifest(libPath) : null;
|
|
5599
|
+
if (!libPath || !manifest || manifest.source) continue;
|
|
5600
|
+
const entry = (manifest.assets ?? []).find(
|
|
5601
|
+
(a) => a.kind === parsed.kind && a.name === parsed.name && !a.source && (!parsed.publisher || bare(a.publisher ?? manifest.publisher) === bare(parsed.publisher))
|
|
5602
|
+
);
|
|
5603
|
+
if (!entry?.root || isAbsolute(entry.root) || entry.root.split(/[\\/]+/).includes("..")) {
|
|
5604
|
+
continue;
|
|
5605
|
+
}
|
|
5606
|
+
const problems = libraryAssetCheck(
|
|
5607
|
+
{ kind: entry.kind, name: entry.name, source: join(libPath, entry.root) },
|
|
5608
|
+
libPath
|
|
5609
|
+
);
|
|
5610
|
+
if (problems.length > 0) {
|
|
5611
|
+
throw new Error(
|
|
5612
|
+
`${parsed.kind}:${parsed.name} in library "${l.name}" fails the checks of \`skaile validate\` - nothing was added:
|
|
5613
|
+
${problems.map((line) => ` ${line}`).join("\n")}
|
|
5614
|
+
Fix the asset, then run \`skaile library index ${l.name}\` and add it again.`
|
|
5615
|
+
);
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5269
5619
|
const unreachable = [...this.storeFailures.values()];
|
|
5270
5620
|
if (unreachable.length > 0) {
|
|
5271
5621
|
throw new Error(
|
|
@@ -5458,9 +5808,15 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
5458
5808
|
}
|
|
5459
5809
|
this.addDependencyToConfig(ref, opts?.only === true);
|
|
5460
5810
|
this.widenDependencyRows(entries, parsed);
|
|
5811
|
+
if (!opts?.preferLockedLibrary) {
|
|
5812
|
+
const bound = this.bindAgentInstance(entries, parsed);
|
|
5813
|
+
if (bound?.keptRef !== void 0) opts?.onAgentBindingKept?.(bound.id, bound.keptRef);
|
|
5814
|
+
else if (bound) opts?.onAgentBound?.(bound.id, bound.ref);
|
|
5815
|
+
}
|
|
5461
5816
|
await this.renderHarnessMcpConfig();
|
|
5462
5817
|
await this.renderAgentInstances();
|
|
5463
5818
|
if (resolved.length > 0 || lib.entries.length > 0) {
|
|
5819
|
+
await this.warnUncommittedLibraryAssets(lib);
|
|
5464
5820
|
const libraryLock = await this.libraryLockEntries(lib);
|
|
5465
5821
|
const fresh = {
|
|
5466
5822
|
...buildLockFile(resolved, overridesApplied, libraryLock),
|
|
@@ -6269,17 +6625,18 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
6269
6625
|
listStaleHarnessCopies() {
|
|
6270
6626
|
if (this.global) return [];
|
|
6271
6627
|
const tracked = /* @__PURE__ */ new Map();
|
|
6272
|
-
const track = (kind, name) => {
|
|
6628
|
+
const track = (kind, name, locked = false) => {
|
|
6273
6629
|
const component = kind ? this.installTarget(kind) : void 0;
|
|
6274
6630
|
if (kind && name && component) {
|
|
6275
|
-
|
|
6631
|
+
const key = `${kind}:${name}`;
|
|
6632
|
+
tracked.set(key, { kind, name, component, locked: locked || !!tracked.get(key)?.locked });
|
|
6276
6633
|
}
|
|
6277
6634
|
};
|
|
6278
6635
|
const lock = this.tryReadLock();
|
|
6279
6636
|
if (lock) {
|
|
6280
6637
|
for (const key of Object.keys(lock.assets)) {
|
|
6281
6638
|
const { kind, name } = parseCanonicalLockKey(key);
|
|
6282
|
-
track(kind, name);
|
|
6639
|
+
track(kind, name, true);
|
|
6283
6640
|
}
|
|
6284
6641
|
}
|
|
6285
6642
|
try {
|
|
@@ -6295,23 +6652,36 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
6295
6652
|
const out = [];
|
|
6296
6653
|
for (const other of SUPPORTED_HARNESSES) {
|
|
6297
6654
|
if (other === this.harness) continue;
|
|
6298
|
-
for (const { kind, name, component: k } of tracked.values()) {
|
|
6655
|
+
for (const { kind, name, component: k, locked } of tracked.values()) {
|
|
6299
6656
|
if (deployedDir(k, name, other, false, this.projectDir) === deployedDir(k, name, this.harness, false, this.projectDir)) {
|
|
6300
6657
|
continue;
|
|
6301
6658
|
}
|
|
6302
|
-
const
|
|
6659
|
+
const footprints = deployedPaths(k, name, other, false, this.projectDir);
|
|
6660
|
+
if (k === "agent" && other === "codex") {
|
|
6661
|
+
footprints.push(
|
|
6662
|
+
join(
|
|
6663
|
+
dirname(deployedBase(k, other, false, this.projectDir)),
|
|
6664
|
+
CODEX_IDENTITY_DIR,
|
|
6665
|
+
`${name}.md`
|
|
6666
|
+
)
|
|
6667
|
+
);
|
|
6668
|
+
}
|
|
6669
|
+
const otherBase = deployedBase(k, other, false, this.projectDir);
|
|
6670
|
+
const activeBase = deployedBase(k, this.harness, false, this.projectDir);
|
|
6671
|
+
for (const p of footprints) {
|
|
6303
6672
|
try {
|
|
6304
6673
|
lstatSync(p);
|
|
6305
|
-
return true;
|
|
6306
6674
|
} catch {
|
|
6307
|
-
|
|
6675
|
+
continue;
|
|
6308
6676
|
}
|
|
6309
|
-
|
|
6310
|
-
|
|
6677
|
+
const twin = join(activeBase, relative(otherBase, p));
|
|
6678
|
+
const skaileWrote = k === "agent" ? locked : !relative(otherBase, p).startsWith("..") && sameBytes(p, twin);
|
|
6679
|
+
out.push({ harness: other, kind, name, path: p, skaileWrote });
|
|
6680
|
+
}
|
|
6311
6681
|
}
|
|
6312
6682
|
}
|
|
6313
6683
|
return out.sort(
|
|
6314
|
-
(a, b) => a.harness.localeCompare(b.harness) || a.kind.localeCompare(b.kind) || a.name.localeCompare(b.name)
|
|
6684
|
+
(a, b) => a.harness.localeCompare(b.harness) || a.kind.localeCompare(b.kind) || a.name.localeCompare(b.name) || a.path.localeCompare(b.path)
|
|
6315
6685
|
);
|
|
6316
6686
|
}
|
|
6317
6687
|
/**
|
|
@@ -6558,7 +6928,13 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
6558
6928
|
const locked = parsed.kind === "preset" ? lock !== null : lockKeys.some(
|
|
6559
6929
|
(k) => k.kind === parsed.kind && k.name === parsed.name && (!parsed.publisher || k.publisher === parsed.publisher)
|
|
6560
6930
|
);
|
|
6561
|
-
|
|
6931
|
+
let recorded = this.entryHarnessRecord(parsed.kind, parsed.name, parsed.publisher);
|
|
6932
|
+
if (!recorded && this.isLegacyHarnessRecord()) {
|
|
6933
|
+
const all = this.defaultGlobalHarnesses();
|
|
6934
|
+
const component = this.installTarget(parsed.kind);
|
|
6935
|
+
const holding = all.length >= 2 && component ? this.legacySingleCopyHarness(component, parsed.name, all) : [];
|
|
6936
|
+
if (holding.length === 1) recorded = holding;
|
|
6937
|
+
}
|
|
6562
6938
|
for (const harness of recorded ? harnesses.filter((h) => recorded.includes(h)) : harnesses) {
|
|
6563
6939
|
let state;
|
|
6564
6940
|
if (!locked) {
|
|
@@ -6843,6 +7219,13 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
6843
7219
|
if (!decl) continue;
|
|
6844
7220
|
const status = checkRepoStatus(decl, slug, this.reposDir);
|
|
6845
7221
|
if (status.kind !== "remote" || !status.localHead) continue;
|
|
7222
|
+
if (status.error !== void 0) {
|
|
7223
|
+
this.unreachableSources.push({
|
|
7224
|
+
name: sourceShortName(src.url),
|
|
7225
|
+
url: src.url,
|
|
7226
|
+
reason: status.error
|
|
7227
|
+
});
|
|
7228
|
+
}
|
|
6846
7229
|
const clone = decl.path ?? join(this.reposDir, slug);
|
|
6847
7230
|
for (const [ref, entry] of Object.entries(lock.assets)) {
|
|
6848
7231
|
if (entry.source?.url !== src.url) continue;
|
|
@@ -7500,7 +7883,7 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
7500
7883
|
break;
|
|
7501
7884
|
}
|
|
7502
7885
|
librarySnap ??= { snap: await this.loadLibraryIndex() };
|
|
7503
|
-
if (await this.
|
|
7886
|
+
if (await this.restoredFromStoreCache(key, e, librarySnap.snap)) {
|
|
7504
7887
|
restorable = true;
|
|
7505
7888
|
break;
|
|
7506
7889
|
}
|
|
@@ -7702,11 +8085,15 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
7702
8085
|
named.add(gapIdentity(ref));
|
|
7703
8086
|
}
|
|
7704
8087
|
for (const d of await this.lockedCopyDrift()) {
|
|
7705
|
-
if (named.has(gapIdentity(d.ref)))
|
|
8088
|
+
if (named.has(gapIdentity(d.ref))) {
|
|
8089
|
+
const at = d.libraryChanged ? gaps.findIndex((g) => g.type === "content" && gapIdentity(g.ref) === gapIdentity(d.ref)) : -1;
|
|
8090
|
+
if (at < 0) continue;
|
|
8091
|
+
gaps.splice(at, 1);
|
|
8092
|
+
}
|
|
7706
8093
|
const parts = [
|
|
7707
8094
|
...d.modified.map((f) => {
|
|
7708
8095
|
const instance = d.instanceOf?.get(f);
|
|
7709
|
-
return instance ? `${f}, the file of agent instance "${instance}", was edited` : `${f} was edited`;
|
|
8096
|
+
return instance ? `${f}, the file of agent instance "${instance}", was edited` : d.unrecorded ? `${f} differs from the library's content now (the lock keeps no per-file record: it may be a library change, not your edit)` : `${f} was edited`;
|
|
7710
8097
|
}),
|
|
7711
8098
|
...d.extra.map((f) => `${f} is not part of the asset`)
|
|
7712
8099
|
];
|
|
@@ -7982,7 +8369,7 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
7982
8369
|
found.version
|
|
7983
8370
|
);
|
|
7984
8371
|
if (!diskVersion || isPseudoVersion(diskVersion) || !gt(coerceVersion(diskVersion), coerceVersion(origin.version)) && (isPseudoVersion(origin.version) || diskVersion === origin.version)) {
|
|
7985
|
-
const reason2 = `is locked, but library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; run \`skaile
|
|
8372
|
+
const reason2 = `is locked, but library "${lookup.name}" content changed since lock \u2014 or the lock predates the one shared asset hash; run \`skaile update\` to re-lock it`;
|
|
7986
8373
|
gaps.push({ type: "content", ref, reason: reason2, message: `${ref} ${reason2}` });
|
|
7987
8374
|
}
|
|
7988
8375
|
}
|
|
@@ -7995,7 +8382,7 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
7995
8382
|
continue;
|
|
7996
8383
|
}
|
|
7997
8384
|
if (lookup.state === "unregistered") {
|
|
7998
|
-
if (await this.
|
|
8385
|
+
if (await this.restoredFromStoreCache(key, entry, snap)) continue;
|
|
7999
8386
|
const reason2 = `is locked, but library "${unregisteredLibraryName(origin)}" is not registered (renamed or removed?) \u2014 ${unregisteredLibraryFix(origin, ref)}`;
|
|
8000
8387
|
gaps.push({ type: "library", ref, reason: reason2, message: `${ref} ${reason2}`, manualFix: true });
|
|
8001
8388
|
continue;
|
|
@@ -8037,16 +8424,19 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8037
8424
|
for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
8038
8425
|
const url = entry.source?.url;
|
|
8039
8426
|
if (!url || entry.library || !GIT_URL.test(url)) continue;
|
|
8427
|
+
if (entry.origin === "store" && !online) continue;
|
|
8040
8428
|
if (inScope && !inScope.has(key)) continue;
|
|
8041
|
-
if (
|
|
8429
|
+
if (isBundledFactoryEntry(entry)) continue;
|
|
8042
8430
|
const { publisher, kind, name, version } = parseCanonicalLockKey(key);
|
|
8043
8431
|
if (!publisher || !kind || !name) continue;
|
|
8044
8432
|
if (registered.has(sourceCacheKey(url))) continue;
|
|
8045
8433
|
const ref = `${kind}:@${publisher}/${name}`;
|
|
8046
8434
|
const locked = version ? `${ref}#${version}` : void 0;
|
|
8047
|
-
|
|
8435
|
+
const askStores = entry.origin === "store" && entry.store && !stores.some((s) => s.url === entry.store) ? [...stores, { url: entry.store }] : stores;
|
|
8436
|
+
if (GITHUB_REPO_URL.test(url) && await this.storeListsRef(askStores, ref, online, locked))
|
|
8048
8437
|
continue;
|
|
8049
|
-
const
|
|
8438
|
+
const base = `is locked, but its source ${url} is not in skaile.yaml sources: any more \u2014 register it again with \`skaile source add ${url}\`, or drop the dependency with \`skaile remove ${ref}\``;
|
|
8439
|
+
const reason = stores.length > 0 && GITHUB_REPO_URL.test(url) && entry.origin !== "store" ? `${base}. If a store supplied it (store unreachable, or its cache is cold), run \`skaile install\` with the store online to record the store as its origin` : base;
|
|
8050
8440
|
out.set(key, { type: "source", ref, reason, message: `${ref} ${reason}`, manualFix: true });
|
|
8051
8441
|
}
|
|
8052
8442
|
return out;
|
|
@@ -8059,6 +8449,7 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8059
8449
|
* its cached catalog holds.
|
|
8060
8450
|
*/
|
|
8061
8451
|
async storeListsRef(stores, ref, online, lockedRef) {
|
|
8452
|
+
if (online && this.catalogUrlOverride === "") return true;
|
|
8062
8453
|
for (const store of stores) {
|
|
8063
8454
|
try {
|
|
8064
8455
|
if (this.injectedStoreFetcher) {
|
|
@@ -8095,8 +8486,8 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8095
8486
|
const gaps = [];
|
|
8096
8487
|
for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
8097
8488
|
const url = entry.source?.url;
|
|
8098
|
-
if (!url || entry.library || !GIT_URL.test(url)) continue;
|
|
8099
|
-
if (
|
|
8489
|
+
if (!url || entry.library || entry.origin === "store" || !GIT_URL.test(url)) continue;
|
|
8490
|
+
if (isBundledFactoryEntry(entry)) continue;
|
|
8100
8491
|
const { publisher, kind, name } = parseCanonicalLockKey(key);
|
|
8101
8492
|
if (!publisher || !kind || !name || named.has(`${kind}:${name}`)) continue;
|
|
8102
8493
|
const ref = `${kind}:@${publisher}/${name}`;
|
|
@@ -8124,7 +8515,8 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8124
8515
|
const want = sourceCacheKey(url);
|
|
8125
8516
|
const out = [];
|
|
8126
8517
|
for (const [key, entry] of Object.entries(this.tryReadLock()?.assets ?? {})) {
|
|
8127
|
-
if (entry.library || !entry.source ||
|
|
8518
|
+
if (entry.library || !entry.source || isFactoryMemorySource(entry.source)) continue;
|
|
8519
|
+
if (sourceCacheKey(entry.source.url) !== want) continue;
|
|
8128
8520
|
const { publisher, kind, name } = parseCanonicalLockKey(key);
|
|
8129
8521
|
if (kind && name) out.push(publisher ? `${kind}:@${publisher}/${name}` : `${kind}:${name}`);
|
|
8130
8522
|
}
|
|
@@ -8439,7 +8831,15 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8439
8831
|
})?.modified ?? [];
|
|
8440
8832
|
}
|
|
8441
8833
|
if (modified.length > 0) {
|
|
8442
|
-
out.push({
|
|
8834
|
+
out.push({
|
|
8835
|
+
ref,
|
|
8836
|
+
key,
|
|
8837
|
+
modified,
|
|
8838
|
+
extra: [],
|
|
8839
|
+
library: true,
|
|
8840
|
+
libraryChanged: true,
|
|
8841
|
+
...entry.copied && entry.copied.length > 0 ? {} : { unrecorded: true }
|
|
8842
|
+
});
|
|
8443
8843
|
}
|
|
8444
8844
|
}
|
|
8445
8845
|
return out;
|
|
@@ -8487,15 +8887,10 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8487
8887
|
const ref = `${e.kind}:@${(e.publisher ?? "").replace(/^@/, "")}/${e.name}`;
|
|
8488
8888
|
out.push({ ref, key: keyOf.get(ref) ?? ref, ...drift, library: true });
|
|
8489
8889
|
}
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
lock,
|
|
8493
|
-
new Set(
|
|
8494
|
-
entries.map((e) => `${e.kind}:@${(e.publisher ?? "").replace(/^@/, "")}/${e.name}`)
|
|
8495
|
-
),
|
|
8496
|
-
patches
|
|
8497
|
-
)
|
|
8890
|
+
const restoredRefs = new Set(
|
|
8891
|
+
entries.map((e) => `${e.kind}:@${(e.publisher ?? "").replace(/^@/, "")}/${e.name}`)
|
|
8498
8892
|
);
|
|
8893
|
+
out.push(...await this.changedLibraryCopyEdits(lock, restoredRefs, patches));
|
|
8499
8894
|
for (const [key, entry] of Object.entries(lock.assets)) {
|
|
8500
8895
|
if (!entry.source || entry.files.length === 0) continue;
|
|
8501
8896
|
const { kind, name } = parseCanonicalLockKey(key);
|
|
@@ -8529,6 +8924,7 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8529
8924
|
if (modified.length > 0 || extra.length > 0)
|
|
8530
8925
|
out.push({ ref: refOf(key), key, modified, extra, library: false });
|
|
8531
8926
|
}
|
|
8927
|
+
let snapForAgents;
|
|
8532
8928
|
for (const [key, entry] of Object.entries(lock.assets)) {
|
|
8533
8929
|
const recorded = [...entry.rendered ?? [], ...entry.composed ?? []];
|
|
8534
8930
|
if (recorded.length === 0 || entry.library?.installed) continue;
|
|
@@ -8550,12 +8946,24 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
8550
8946
|
for (const inst of renderedInstanceFiles(this.projectDir, this.harness)) {
|
|
8551
8947
|
for (const f of inst.files) if (modified.includes(f)) instanceOf.set(f, inst.id);
|
|
8552
8948
|
}
|
|
8949
|
+
let libraryChanged = false;
|
|
8950
|
+
const origin = entry.library;
|
|
8951
|
+
const id = parseCanonicalLockKey(key);
|
|
8952
|
+
if (origin && id.publisher && !restoredRefs.has(refOf(key))) {
|
|
8953
|
+
snapForAgents ??= await this.loadLibraryIndex();
|
|
8954
|
+
libraryChanged = this.lockedLibrary(origin, snapForAgents, {
|
|
8955
|
+
kind,
|
|
8956
|
+
publisher: id.publisher,
|
|
8957
|
+
name
|
|
8958
|
+
}).state === "ok";
|
|
8959
|
+
}
|
|
8553
8960
|
out.push({
|
|
8554
8961
|
ref: refOf(key),
|
|
8555
8962
|
key,
|
|
8556
8963
|
modified,
|
|
8557
8964
|
extra: [],
|
|
8558
8965
|
library: false,
|
|
8966
|
+
...libraryChanged ? { libraryChanged: true } : {},
|
|
8559
8967
|
rendered: true,
|
|
8560
8968
|
lockedSha: new Map(recorded.map((f) => [f.path, f.sha256])),
|
|
8561
8969
|
instanceOf
|
|
@@ -9085,6 +9493,53 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
9085
9493
|
}
|
|
9086
9494
|
return out;
|
|
9087
9495
|
}
|
|
9496
|
+
/**
|
|
9497
|
+
* Bind the agent `skaile add agent:<ref>` just added as an instance `agents.<name>:
|
|
9498
|
+
* {ref: agent:@publisher/name}` of `skaile.yaml`, so `run --instance <name>` and the repl
|
|
9499
|
+
* banner hint work at once. An agent that an instance or `agent:` already binds, or an id
|
|
9500
|
+
* `agents:` already holds, is left as it is. Project mode only.
|
|
9501
|
+
*
|
|
9502
|
+
* @returns the instance id and ref bound; the id with `keptRef` (what that id binds instead)
|
|
9503
|
+
* when the id is taken by another agent; `undefined` when nothing was bound and nothing needs saying.
|
|
9504
|
+
*/
|
|
9505
|
+
bindAgentInstance(entries, parsed) {
|
|
9506
|
+
if (this.global || parsed.kind !== "agent") return void 0;
|
|
9507
|
+
const configPath = join(this.stateRoot, "skaile.yaml");
|
|
9508
|
+
if (!existsSync(configPath)) return void 0;
|
|
9509
|
+
const bare = (p) => p?.replace(/^@/, "");
|
|
9510
|
+
const entry = entries.find(
|
|
9511
|
+
(e) => e.kind === "agent" && e.name === parsed.name && (!parsed.publisher || bare(e.publisher) === bare(parsed.publisher))
|
|
9512
|
+
);
|
|
9513
|
+
const publisher = bare(entry?.publisher ?? parsed.publisher);
|
|
9514
|
+
const ref = publisher ? `agent:@${publisher}/${parsed.name}` : `agent:${parsed.name}`;
|
|
9515
|
+
const id = parsed.name.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^[^a-z]+/, "");
|
|
9516
|
+
if (!/^[a-z][a-z0-9_-]*$/.test(id)) return void 0;
|
|
9517
|
+
let raw;
|
|
9518
|
+
try {
|
|
9519
|
+
raw = parse(readFileSync(configPath, "utf8"));
|
|
9520
|
+
} catch {
|
|
9521
|
+
return void 0;
|
|
9522
|
+
}
|
|
9523
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
9524
|
+
const bound = (value) => {
|
|
9525
|
+
const p = typeof value === "string" ? parseRefTolerant(value) : null;
|
|
9526
|
+
return !!p && p.kind === "agent" && p.name === parsed.name && (!publisher || !p.publisher || bare(p.publisher) === publisher);
|
|
9527
|
+
};
|
|
9528
|
+
const instances = raw.agents && typeof raw.agents === "object" && !Array.isArray(raw.agents) ? raw.agents : {};
|
|
9529
|
+
const primary = raw.agent && typeof raw.agent === "object" ? raw.agent.definition : void 0;
|
|
9530
|
+
if (bound(primary) || Object.values(instances).some((i) => bound(i?.ref))) {
|
|
9531
|
+
return void 0;
|
|
9532
|
+
}
|
|
9533
|
+
const taken = instances[id]?.ref;
|
|
9534
|
+
if (id in instances)
|
|
9535
|
+
return { id, ref, keptRef: typeof taken === "string" ? taken : "another agent" };
|
|
9536
|
+
if (id === DEFAULT_AGENT_INSTANCE_ID && typeof primary === "string") {
|
|
9537
|
+
return { id, ref, keptRef: primary };
|
|
9538
|
+
}
|
|
9539
|
+
raw.agents = { ...instances, [id]: { ref } };
|
|
9540
|
+
writeFileSync(configPath, stringify(raw, { lineWidth: 120 }));
|
|
9541
|
+
return { id, ref };
|
|
9542
|
+
}
|
|
9088
9543
|
/** The refs `skaile.yaml` binds agent instances to: every `agents.<id>.ref` and `agent.definition`. Project mode only. */
|
|
9089
9544
|
declaredAgentInstanceRefs() {
|
|
9090
9545
|
if (this.global) return [];
|
|
@@ -9167,5 +9622,5 @@ Fix the asset in the source repo, then run \`skaile source sync\` and add it aga
|
|
|
9167
9622
|
};
|
|
9168
9623
|
|
|
9169
9624
|
export { AssetManager, LibraryEntryError, MissingManifestError, installAgentInstances, labelDiffHeaders, mcpNotRunnableReason, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, setLibraryAssetCheck, setRenamedEntryLookup, softDepName };
|
|
9170
|
-
//# sourceMappingURL=chunk-
|
|
9171
|
-
//# sourceMappingURL=chunk-
|
|
9625
|
+
//# sourceMappingURL=chunk-IS3NIZBX.js.map
|
|
9626
|
+
//# sourceMappingURL=chunk-IS3NIZBX.js.map
|