@credibledata/cred-cli 0.0.103 → 0.0.105
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/README.md +106 -1
- package/dist/agent-contract.spec.js +548 -0
- package/dist/agent-contract.spec.js.map +1 -0
- package/dist/browser.js +72 -0
- package/dist/browser.js.map +1 -0
- package/dist/browser.spec.js +125 -0
- package/dist/browser.spec.js.map +1 -0
- package/dist/client/api.js +4137 -1159
- package/dist/client/api.js.map +1 -1
- package/dist/client-codeassist/api.js +476 -0
- package/dist/client-codeassist/api.js.map +1 -0
- package/dist/client-codeassist/base.js +69 -0
- package/dist/client-codeassist/base.js.map +1 -0
- package/dist/client-codeassist/common.js +162 -0
- package/dist/client-codeassist/common.js.map +1 -0
- package/dist/client-codeassist/configuration.js +44 -0
- package/dist/client-codeassist/configuration.js.map +1 -0
- package/dist/client-codeassist/index.js +32 -0
- package/dist/client-codeassist/index.js.map +1 -0
- package/dist/clientconfiguration.js +17 -289
- package/dist/clientconfiguration.js.map +1 -1
- package/dist/clientconfiguration.spec.js +35 -96
- package/dist/clientconfiguration.spec.js.map +1 -1
- package/dist/commands/add.js +103 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/add.spec.js +113 -0
- package/dist/commands/add.spec.js.map +1 -0
- package/dist/commands/connection/createconnections.js +104 -7
- package/dist/commands/connection/createconnections.js.map +1 -1
- package/dist/commands/connection/createconnections.spec.js +35 -1
- package/dist/commands/connection/createconnections.spec.js.map +1 -1
- package/dist/commands/connection/deleteconnection.js +4 -2
- package/dist/commands/connection/deleteconnection.js.map +1 -1
- package/dist/commands/connection/deleteconnection.spec.js +6 -1
- package/dist/commands/connection/deleteconnection.spec.js.map +1 -1
- package/dist/commands/connection/listconnections.js +2 -0
- package/dist/commands/connection/listconnections.js.map +1 -1
- package/dist/commands/connection/updateconnection.js +365 -0
- package/dist/commands/connection/updateconnection.js.map +1 -0
- package/dist/commands/connection/updateconnection.spec.js +625 -0
- package/dist/commands/connection/updateconnection.spec.js.map +1 -0
- package/dist/commands/database/createdatabase.js +52 -0
- package/dist/commands/database/createdatabase.js.map +1 -0
- package/dist/commands/database/database.spec.js +267 -0
- package/dist/commands/database/database.spec.js.map +1 -0
- package/dist/commands/database/deletedatabase.js +91 -0
- package/dist/commands/database/deletedatabase.js.map +1 -0
- package/dist/commands/database/getdatabase.js +97 -0
- package/dist/commands/database/getdatabase.js.map +1 -0
- package/dist/commands/database/listdatabases.js +36 -0
- package/dist/commands/database/listdatabases.js.map +1 -0
- package/dist/commands/database/shared.js +125 -0
- package/dist/commands/database/shared.js.map +1 -0
- package/dist/commands/database/shared.spec.js +109 -0
- package/dist/commands/database/shared.spec.js.map +1 -0
- package/dist/commands/database/updatedatabase.js +39 -0
- package/dist/commands/database/updatedatabase.js.map +1 -0
- package/dist/commands/environment/createenvironment.js +59 -28
- package/dist/commands/environment/createenvironment.js.map +1 -1
- package/dist/commands/environment/createenvironment.spec.js +29 -0
- package/dist/commands/environment/createenvironment.spec.js.map +1 -1
- package/dist/commands/environment/deleteenvironment.js +3 -2
- package/dist/commands/environment/deleteenvironment.js.map +1 -1
- package/dist/commands/environment/deleteenvironment.spec.js +5 -1
- package/dist/commands/environment/deleteenvironment.spec.js.map +1 -1
- package/dist/commands/environment/getenvironment.js +1 -0
- package/dist/commands/environment/getenvironment.js.map +1 -1
- package/dist/commands/environment/listenvironments.js +40 -8
- package/dist/commands/environment/listenvironments.js.map +1 -1
- package/dist/commands/environment/listenvironments.spec.js +41 -2
- package/dist/commands/environment/listenvironments.spec.js.map +1 -1
- package/dist/commands/environment/setenvironment.js +145 -6
- package/dist/commands/environment/setenvironment.js.map +1 -1
- package/dist/commands/environment/setenvironment.spec.js +256 -8
- package/dist/commands/environment/setenvironment.spec.js.map +1 -1
- package/dist/commands/environment/updateenvironment.js +12 -8
- package/dist/commands/environment/updateenvironment.js.map +1 -1
- package/dist/commands/environment/updateenvironment.spec.js +36 -2
- package/dist/commands/environment/updateenvironment.spec.js.map +1 -1
- package/dist/commands/get.js +64 -1
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/group/addmember.js +3 -1
- package/dist/commands/group/addmember.js.map +1 -1
- package/dist/commands/group/addmember.spec.js +7 -2
- package/dist/commands/group/addmember.spec.js.map +1 -1
- package/dist/commands/group/creategroup.js +2 -0
- package/dist/commands/group/creategroup.js.map +1 -1
- package/dist/commands/group/deletegroup.js +3 -1
- package/dist/commands/group/deletegroup.js.map +1 -1
- package/dist/commands/group/deletegroup.spec.js +7 -1
- package/dist/commands/group/deletegroup.spec.js.map +1 -1
- package/dist/commands/group/getgroup.js +2 -0
- package/dist/commands/group/getgroup.js.map +1 -1
- package/dist/commands/group/listgroups.js +2 -0
- package/dist/commands/group/listgroups.js.map +1 -1
- package/dist/commands/group/removemember.js +3 -1
- package/dist/commands/group/removemember.js.map +1 -1
- package/dist/commands/group/removemember.spec.js +7 -2
- package/dist/commands/group/removemember.spec.js.map +1 -1
- package/dist/commands/groupaccesstoken/deleteToken.js +2 -1
- package/dist/commands/groupaccesstoken/deleteToken.js.map +1 -1
- package/dist/commands/groupaccesstoken/groupContainer.js +2 -0
- package/dist/commands/groupaccesstoken/groupContainer.js.map +1 -1
- package/dist/commands/list.js +24 -4
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/materialization/cancelrun.js +3 -1
- package/dist/commands/materialization/cancelrun.js.map +1 -1
- package/dist/commands/materialization/getindex.js +2 -0
- package/dist/commands/materialization/getindex.js.map +1 -1
- package/dist/commands/materialization/getmaterialization.js +2 -0
- package/dist/commands/materialization/getmaterialization.js.map +1 -1
- package/dist/commands/materialization/getpreaggregate.js +2 -0
- package/dist/commands/materialization/getpreaggregate.js.map +1 -1
- package/dist/commands/materialization/getrun.js +2 -0
- package/dist/commands/materialization/getrun.js.map +1 -1
- package/dist/commands/materialization/listindexes.js +2 -0
- package/dist/commands/materialization/listindexes.js.map +1 -1
- package/dist/commands/materialization/listmaterializations.js +2 -0
- package/dist/commands/materialization/listmaterializations.js.map +1 -1
- package/dist/commands/materialization/listpreaggregates.js +2 -0
- package/dist/commands/materialization/listpreaggregates.js.map +1 -1
- package/dist/commands/materialization/listruns.js +3 -1
- package/dist/commands/materialization/listruns.js.map +1 -1
- package/dist/commands/materialization/rerun.js +3 -1
- package/dist/commands/materialization/rerun.js.map +1 -1
- package/dist/commands/misc/inquirerHost.js +87 -0
- package/dist/commands/misc/inquirerHost.js.map +1 -0
- package/dist/commands/misc/inquirerHost.spec.js +91 -0
- package/dist/commands/misc/inquirerHost.spec.js.map +1 -0
- package/dist/commands/misc/login.js +348 -58
- package/dist/commands/misc/login.js.map +1 -1
- package/dist/commands/misc/login.spec.js +525 -7
- package/dist/commands/misc/login.spec.js.map +1 -1
- package/dist/commands/misc/logout.js +26 -3
- package/dist/commands/misc/logout.js.map +1 -1
- package/dist/commands/misc/logout.spec.js +52 -12
- package/dist/commands/misc/logout.spec.js.map +1 -1
- package/dist/commands/misc/resolveLoginTarget.spec.js +90 -0
- package/dist/commands/misc/resolveLoginTarget.spec.js.map +1 -0
- package/dist/commands/misc/scope.spec.js +108 -0
- package/dist/commands/misc/scope.spec.js.map +1 -0
- package/dist/commands/misc/set-access-token.js +1 -1
- package/dist/commands/misc/set-access-token.js.map +1 -1
- package/dist/commands/misc/set-access-token.spec.js +13 -2
- package/dist/commands/misc/set-access-token.spec.js.map +1 -1
- package/dist/commands/misc/setup.js +819 -0
- package/dist/commands/misc/setup.js.map +1 -0
- package/dist/commands/misc/setup.spec.js +783 -0
- package/dist/commands/misc/setup.spec.js.map +1 -0
- package/dist/commands/misc/status.js +168 -0
- package/dist/commands/misc/status.js.map +1 -0
- package/dist/commands/misc/status.spec.js +301 -0
- package/dist/commands/misc/status.spec.js.map +1 -0
- package/dist/commands/misc/token.js +57 -0
- package/dist/commands/misc/token.js.map +1 -0
- package/dist/commands/misc/token.spec.js +92 -0
- package/dist/commands/misc/token.spec.js.map +1 -0
- package/dist/commands/package/deletepackage.js +4 -2
- package/dist/commands/package/deletepackage.js.map +1 -1
- package/dist/commands/package/deletepackage.spec.js +7 -1
- package/dist/commands/package/deletepackage.spec.js.map +1 -1
- package/dist/commands/package/getpackage.js +142 -0
- package/dist/commands/package/getpackage.js.map +1 -0
- package/dist/commands/package/getpackage.spec.js +246 -0
- package/dist/commands/package/getpackage.spec.js.map +1 -0
- package/dist/commands/package/listpackages.js +2 -0
- package/dist/commands/package/listpackages.js.map +1 -1
- package/dist/commands/package/publish.archive.spec.js +570 -0
- package/dist/commands/package/publish.archive.spec.js.map +1 -0
- package/dist/commands/package/publish.js +780 -49
- package/dist/commands/package/publish.js.map +1 -1
- package/dist/commands/package/publish.spec.js +451 -8
- package/dist/commands/package/publish.spec.js.map +1 -1
- package/dist/commands/package/updatepackage.js +22 -19
- package/dist/commands/package/updatepackage.js.map +1 -1
- package/dist/commands/package/updatepackage.spec.js +36 -1
- package/dist/commands/package/updatepackage.spec.js.map +1 -1
- package/dist/commands/permission/createpermission.js +3 -1
- package/dist/commands/permission/createpermission.js.map +1 -1
- package/dist/commands/permission/deletepermission.js +6 -3
- package/dist/commands/permission/deletepermission.js.map +1 -1
- package/dist/commands/permission/getpermission.js +2 -0
- package/dist/commands/permission/getpermission.js.map +1 -1
- package/dist/commands/permission/listpermissions.js +2 -0
- package/dist/commands/permission/listpermissions.js.map +1 -1
- package/dist/commands/rm.js +21 -0
- package/dist/commands/rm.js.map +1 -1
- package/dist/commands/set.js +40 -6
- package/dist/commands/set.js.map +1 -1
- package/dist/commands/set.spec.js +123 -0
- package/dist/commands/set.spec.js.map +1 -0
- package/dist/commands/table/addtable.js +155 -0
- package/dist/commands/table/addtable.js.map +1 -0
- package/dist/commands/table/deletetable.js +45 -0
- package/dist/commands/table/deletetable.js.map +1 -0
- package/dist/commands/table/gettable.js +32 -0
- package/dist/commands/table/gettable.js.map +1 -0
- package/dist/commands/table/listtables.js +36 -0
- package/dist/commands/table/listtables.js.map +1 -0
- package/dist/commands/table/table.spec.js +304 -0
- package/dist/commands/table/table.spec.js.map +1 -0
- package/dist/commands/table/tablefile.js +195 -0
- package/dist/commands/table/tablefile.js.map +1 -0
- package/dist/commands/table/tablefile.spec.js +158 -0
- package/dist/commands/table/tablefile.spec.js.map +1 -0
- package/dist/commands/update.js +21 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/version/archive-unarchive-version.js +4 -2
- package/dist/commands/version/archive-unarchive-version.js.map +1 -1
- package/dist/commands/version/archive-unarchive-version.spec.js +6 -1
- package/dist/commands/version/archive-unarchive-version.spec.js.map +1 -1
- package/dist/commands/version/listversions.js +2 -0
- package/dist/commands/version/listversions.js.map +1 -1
- package/dist/common/UserGroupId.js +9 -4
- package/dist/common/UserGroupId.js.map +1 -1
- package/dist/common/UserGroupId.spec.js +5 -0
- package/dist/common/UserGroupId.spec.js.map +1 -1
- package/dist/constants.js +37 -143
- package/dist/constants.js.map +1 -1
- package/dist/index.js +487 -90
- package/dist/index.js.map +1 -1
- package/dist/logger.js +42 -9
- package/dist/logger.js.map +1 -1
- package/dist/session.js +56 -0
- package/dist/session.js.map +1 -0
- package/dist/session.spec.js +103 -0
- package/dist/session.spec.js.map +1 -0
- package/dist/setup-core/briefing.js +176 -0
- package/dist/setup-core/briefing.js.map +1 -0
- package/dist/setup-core/credstore.js +415 -0
- package/dist/setup-core/credstore.js.map +1 -0
- package/dist/setup-core/credstore.spec.js +238 -0
- package/dist/setup-core/credstore.spec.js.map +1 -0
- package/dist/setup-core/environments.js +267 -0
- package/dist/setup-core/environments.js.map +1 -0
- package/dist/setup-core/flow.e2e.js +165 -0
- package/dist/setup-core/flow.e2e.js.map +1 -0
- package/dist/setup-core/flow.js +765 -0
- package/dist/setup-core/flow.js.map +1 -0
- package/dist/setup-core/flow.spec.js +1348 -0
- package/dist/setup-core/flow.spec.js.map +1 -0
- package/dist/setup-core/folderconfig.js +283 -0
- package/dist/setup-core/folderconfig.js.map +1 -0
- package/dist/setup-core/git.js +97 -0
- package/dist/setup-core/git.js.map +1 -0
- package/dist/setup-core/host.js +77 -0
- package/dist/setup-core/host.js.map +1 -0
- package/dist/setup-core/importconnections.js +470 -0
- package/dist/setup-core/importconnections.js.map +1 -0
- package/dist/setup-core/importconnections.spec.js +594 -0
- package/dist/setup-core/importconnections.spec.js.map +1 -0
- package/dist/setup-core/liveness.js +94 -0
- package/dist/setup-core/liveness.js.map +1 -0
- package/dist/setup-core/liveness.spec.js +59 -0
- package/dist/setup-core/liveness.spec.js.map +1 -0
- package/dist/setup-core/localpublisherconfig.js +26 -0
- package/dist/setup-core/localpublisherconfig.js.map +1 -0
- package/dist/setup-core/localpublisherconfig.spec.js +29 -0
- package/dist/setup-core/localpublisherconfig.spec.js.map +1 -0
- package/dist/setup-core/mcpconfig.js +198 -0
- package/dist/setup-core/mcpconfig.js.map +1 -0
- package/dist/setup-core/mcpconfig.spec.js +205 -0
- package/dist/setup-core/mcpconfig.spec.js.map +1 -0
- package/dist/setup-core/packagemanifest.js +55 -0
- package/dist/setup-core/packagemanifest.js.map +1 -0
- package/dist/setup-core/ports.js +182 -0
- package/dist/setup-core/ports.js.map +1 -0
- package/dist/setup-core/ports.spec.js +173 -0
- package/dist/setup-core/ports.spec.js.map +1 -0
- package/dist/setup-core/publisherconfig.js +268 -0
- package/dist/setup-core/publisherconfig.js.map +1 -0
- package/dist/setup-core/publisherconfig.oracle.js +166 -0
- package/dist/setup-core/publisherconfig.oracle.js.map +1 -0
- package/dist/setup-core/publisherconfig.spec.js +277 -0
- package/dist/setup-core/publisherconfig.spec.js.map +1 -0
- package/dist/setup-core/publisherversion.js +26 -0
- package/dist/setup-core/publisherversion.js.map +1 -0
- package/dist/setup-core/readiness.spec.js +161 -0
- package/dist/setup-core/readiness.spec.js.map +1 -0
- package/dist/setup-core/readylines.js +169 -0
- package/dist/setup-core/readylines.js.map +1 -0
- package/dist/setup-core/readylines.spec.js +70 -0
- package/dist/setup-core/readylines.spec.js.map +1 -0
- package/dist/setup-core/refresh.js +348 -0
- package/dist/setup-core/refresh.js.map +1 -0
- package/dist/setup-core/refresh.spec.js +501 -0
- package/dist/setup-core/refresh.spec.js.map +1 -0
- package/dist/setup-core/skills.js +279 -0
- package/dist/setup-core/skills.js.map +1 -0
- package/dist/setup-core/skills.spec.js +334 -0
- package/dist/setup-core/skills.spec.js.map +1 -0
- package/dist/setup-core/supervisor.js +879 -0
- package/dist/setup-core/supervisor.js.map +1 -0
- package/dist/setup-core/supervisor.spec.js +833 -0
- package/dist/setup-core/supervisor.spec.js.map +1 -0
- package/dist/setup-core/writefile.js +61 -0
- package/dist/setup-core/writefile.js.map +1 -0
- package/dist/setup-core/writefile.spec.js +68 -0
- package/dist/setup-core/writefile.spec.js.map +1 -0
- package/dist/utils.js +409 -3
- package/dist/utils.js.map +1 -1
- package/dist/utils.spec.js +373 -2
- package/dist/utils.spec.js.map +1 -1
- package/dist/versioncheck-refresh.js +18 -0
- package/dist/versioncheck-refresh.js.map +1 -0
- package/dist/versioncheck.js +324 -0
- package/dist/versioncheck.js.map +1 -0
- package/dist/versioncheck.spec.js +587 -0
- package/dist/versioncheck.spec.js.map +1 -0
- package/node_modules/@credibledata/cli-auth/dist/index.d.ts +86 -0
- package/node_modules/@credibledata/cli-auth/dist/index.js +102 -0
- package/node_modules/@credibledata/cli-auth/package.json +19 -0
- package/package.json +18 -6
- package/.github/workflows/build.yml +0 -23
- package/.mocharc.json +0 -10
- package/.prettierignore +0 -2
- package/.prettierrc +0 -4
- package/README-DEV.md +0 -40
- package/coverage/coverage-summary.json +0 -40
- package/coverage/tmp/coverage-2152-1789496974457-0.json +0 -1
- package/coverage/tmp/coverage-2153-1789496954404-0.json +0 -1
- package/docker/Dockerfile.ci +0 -18
- package/docker-compose.yml +0 -18
- package/eslint.config.mjs +0 -45
- package/generate-client.sh +0 -27
- package/mocha.setup.ts +0 -4
- package/openapitools.json +0 -10
- package/src/client/.openapi-generator/FILES +0 -9
- package/src/client/.openapi-generator/VERSION +0 -1
- package/src/client/.openapi-generator-ignore +0 -23
- package/src/client/api.ts +0 -15999
- package/src/client/base.ts +0 -86
- package/src/client/common.ts +0 -150
- package/src/client/configuration.ts +0 -110
- package/src/client/git_push.sh +0 -57
- package/src/client/index.ts +0 -18
- package/src/clientconfiguration.spec.ts +0 -615
- package/src/clientconfiguration.ts +0 -364
- package/src/commands/add.ts +0 -191
- package/src/commands/connection/createconnections.spec.ts +0 -413
- package/src/commands/connection/createconnections.ts +0 -109
- package/src/commands/connection/deleteconnection.spec.ts +0 -189
- package/src/commands/connection/deleteconnection.ts +0 -57
- package/src/commands/connection/listconnections.spec.ts +0 -132
- package/src/commands/connection/listconnections.ts +0 -58
- package/src/commands/environment/createenvironment.spec.ts +0 -249
- package/src/commands/environment/createenvironment.ts +0 -73
- package/src/commands/environment/deleteenvironment.spec.ts +0 -152
- package/src/commands/environment/deleteenvironment.ts +0 -48
- package/src/commands/environment/getenvironment.spec.ts +0 -110
- package/src/commands/environment/getenvironment.ts +0 -43
- package/src/commands/environment/listenvironments.spec.ts +0 -123
- package/src/commands/environment/listenvironments.ts +0 -67
- package/src/commands/environment/setenvironment.spec.ts +0 -63
- package/src/commands/environment/setenvironment.ts +0 -14
- package/src/commands/environment/updateenvironment.spec.ts +0 -386
- package/src/commands/environment/updateenvironment.ts +0 -168
- package/src/commands/get.ts +0 -153
- package/src/commands/group/addmember.spec.ts +0 -257
- package/src/commands/group/addmember.ts +0 -85
- package/src/commands/group/creategroup.spec.ts +0 -146
- package/src/commands/group/creategroup.ts +0 -54
- package/src/commands/group/deletegroup.spec.ts +0 -120
- package/src/commands/group/deletegroup.ts +0 -45
- package/src/commands/group/getgroup.spec.ts +0 -129
- package/src/commands/group/getgroup.ts +0 -47
- package/src/commands/group/listgroups.spec.ts +0 -137
- package/src/commands/group/listgroups.ts +0 -45
- package/src/commands/group/removemember.spec.ts +0 -224
- package/src/commands/group/removemember.ts +0 -75
- package/src/commands/groupaccesstoken/createToken.spec.ts +0 -211
- package/src/commands/groupaccesstoken/createToken.ts +0 -72
- package/src/commands/groupaccesstoken/deleteToken.spec.ts +0 -147
- package/src/commands/groupaccesstoken/deleteToken.ts +0 -29
- package/src/commands/groupaccesstoken/groupContainer.ts +0 -83
- package/src/commands/groupaccesstoken/listTokens.spec.ts +0 -147
- package/src/commands/groupaccesstoken/listTokens.ts +0 -29
- package/src/commands/legacy.ts +0 -5
- package/src/commands/list.ts +0 -326
- package/src/commands/materialization/cancelrun.ts +0 -70
- package/src/commands/materialization/getindex.ts +0 -55
- package/src/commands/materialization/getmaterialization.ts +0 -57
- package/src/commands/materialization/getpreaggregate.ts +0 -58
- package/src/commands/materialization/getrun.ts +0 -55
- package/src/commands/materialization/listindexes.ts +0 -69
- package/src/commands/materialization/listmaterializations.ts +0 -53
- package/src/commands/materialization/listpreaggregates.ts +0 -74
- package/src/commands/materialization/listruns.ts +0 -77
- package/src/commands/materialization/rerun.ts +0 -123
- package/src/commands/misc/login.spec.ts +0 -371
- package/src/commands/misc/login.ts +0 -343
- package/src/commands/misc/logout.spec.ts +0 -32
- package/src/commands/misc/logout.ts +0 -9
- package/src/commands/misc/loopbackOAuth.ts +0 -127
- package/src/commands/misc/set-access-token.spec.ts +0 -95
- package/src/commands/misc/set-access-token.ts +0 -32
- package/src/commands/package/deletepackage.spec.ts +0 -164
- package/src/commands/package/deletepackage.ts +0 -58
- package/src/commands/package/listpackages.spec.ts +0 -163
- package/src/commands/package/listpackages.ts +0 -74
- package/src/commands/package/publish.spec.ts +0 -642
- package/src/commands/package/publish.ts +0 -236
- package/src/commands/package/updatepackage.spec.ts +0 -319
- package/src/commands/package/updatepackage.ts +0 -95
- package/src/commands/permission/createpermission.spec.ts +0 -507
- package/src/commands/permission/createpermission.ts +0 -181
- package/src/commands/permission/deletepermission.ts +0 -117
- package/src/commands/permission/getpermission.ts +0 -115
- package/src/commands/permission/listpermissions.ts +0 -101
- package/src/commands/permission/scope.ts +0 -180
- package/src/commands/rm.ts +0 -146
- package/src/commands/set.ts +0 -25
- package/src/commands/update.ts +0 -107
- package/src/commands/version/archive-unarchive-version.spec.ts +0 -456
- package/src/commands/version/archive-unarchive-version.ts +0 -108
- package/src/commands/version/listversions.spec.ts +0 -138
- package/src/commands/version/listversions.ts +0 -45
- package/src/common/UserGroupId.spec.ts +0 -115
- package/src/common/UserGroupId.ts +0 -137
- package/src/constants.spec.ts +0 -111
- package/src/constants.ts +0 -228
- package/src/index.ts +0 -378
- package/src/logger.spec.ts +0 -158
- package/src/logger.ts +0 -90
- package/src/polyfills/file.polyfill.ts +0 -6
- package/src/utils.spec.ts +0 -135
- package/src/utils.ts +0 -115
- package/src/validator.spec.ts +0 -51
- package/src/validator.ts +0 -44
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SKILLS_FLAG = exports.RULE_FILE_CURSOR = exports.RULE_FILE_CLAUDE = exports.AGENTS_DIR = exports.SKILLS_DIR = exports.SKILLS_MANIFEST = void 0;
|
|
7
|
+
exports.installSkills = installSkills;
|
|
8
|
+
exports.describeVersion = describeVersion;
|
|
9
|
+
exports.skillsGitignoreEntries = skillsGitignoreEntries;
|
|
10
|
+
exports.foreignSkills = foreignSkills;
|
|
11
|
+
exports.moveForeignSkills = moveForeignSkills;
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const writefile_1 = require("./writefile");
|
|
15
|
+
/**
|
|
16
|
+
* Installing the modeling skills into a wired directory.
|
|
17
|
+
*
|
|
18
|
+
* A port of the VS Code extension's `agentSkillsService.ts`, with one deliberate
|
|
19
|
+
* departure. The extension split the manifest into `.claude/skills/`
|
|
20
|
+
* (auto-discovered) and `.credible/skills/` ("supporting", reached only through
|
|
21
|
+
* a `skill:` reference from another skill). In practice agents did not follow
|
|
22
|
+
* those references, so the supporting tier was installed and unused. Everything
|
|
23
|
+
* the manifest lists now goes to `.claude/skills/`, which is also what the
|
|
24
|
+
* Publisher's own scaffolder (`create-malloy-package`) does, so the two agree
|
|
25
|
+
* on where skills live. The manifest's `auto_discovered` list still means
|
|
26
|
+
* something: those are the entry points the rule file names.
|
|
27
|
+
*
|
|
28
|
+
* The skills come from the code-assist API (`GET /agent_skills?manifest=
|
|
29
|
+
* modeling-ide`), whose version is resolved server-side, so nothing here pins
|
|
30
|
+
* one. The extension kept its install state in `workspaceState`; here it is the
|
|
31
|
+
* `skills` block of `.credible/config.json`, the one per-directory file setup
|
|
32
|
+
* already owns.
|
|
33
|
+
*
|
|
34
|
+
* Skills are the judgement half of the local loop — which journey the user is
|
|
35
|
+
* in, which `cred` commands to run and in what order — and they live in the
|
|
36
|
+
* agent-skills repo rather than in this CLI, so the CLI stays the mechanism.
|
|
37
|
+
*/
|
|
38
|
+
/** The manifest the local modeling loop uses. The extension's default too. */
|
|
39
|
+
exports.SKILLS_MANIFEST = "modeling-ide";
|
|
40
|
+
/** Where every skill goes, and where Claude Code discovers them. */
|
|
41
|
+
exports.SKILLS_DIR = ".claude/skills";
|
|
42
|
+
/** The cross-tool copy for Codex, Gemini and friends. */
|
|
43
|
+
exports.AGENTS_DIR = ".agents/skills";
|
|
44
|
+
exports.RULE_FILE_CLAUDE = ".claude/rules/credible-modeling.md";
|
|
45
|
+
exports.RULE_FILE_CURSOR = ".cursor/rules/credible-modeling.mdc";
|
|
46
|
+
exports.SKILLS_FLAG = "--skills <replace|keep|none>";
|
|
47
|
+
/**
|
|
48
|
+
* Write the skills, replacing whatever a previous install wrote.
|
|
49
|
+
*
|
|
50
|
+
* Only files listed in `previous` are ever deleted: a user's own skill under
|
|
51
|
+
* `.claude/skills/` is not ours to touch. A directory already on this version
|
|
52
|
+
* with every file present is left alone, so `cred dev` re-running this each
|
|
53
|
+
* session costs one API call and no writes.
|
|
54
|
+
*/
|
|
55
|
+
function installSkills(directory, response, host, previous) {
|
|
56
|
+
if (previous &&
|
|
57
|
+
previous.manifest === response.manifest &&
|
|
58
|
+
previous.version === response.version &&
|
|
59
|
+
// The two halves version independently, so a `skills_version` bump
|
|
60
|
+
// alone changes every `malloy-*` skill under the same agent-skills tag.
|
|
61
|
+
previous.publisherVersion === response.publisher_skills_version &&
|
|
62
|
+
previous.files.every((file) => fs_1.default.existsSync(path_1.default.join(directory, file)))) {
|
|
63
|
+
return { action: "current", state: previous };
|
|
64
|
+
}
|
|
65
|
+
if (previous)
|
|
66
|
+
deleteFiles(directory, previous.files);
|
|
67
|
+
const written = [
|
|
68
|
+
...writeSkillFiles(directory, response, host),
|
|
69
|
+
...writeRuleFiles(directory, response),
|
|
70
|
+
];
|
|
71
|
+
const state = Object.assign(Object.assign({ manifest: response.manifest, version: response.version }, (response.publisher_skills_version
|
|
72
|
+
? { publisherVersion: response.publisher_skills_version }
|
|
73
|
+
: {})), { files: written });
|
|
74
|
+
host.log("info", `${previous ? "Updated" : "Installed"} the ${response.manifest} skills (${describeVersion(state)}, ${written.length} files) under ${exports.SKILLS_DIR}/.`);
|
|
75
|
+
return { action: previous ? "updated" : "installed", state };
|
|
76
|
+
}
|
|
77
|
+
/** Both halves' versions, as `cred init` and `cred status` print them. */
|
|
78
|
+
function describeVersion(state) {
|
|
79
|
+
return state.publisherVersion
|
|
80
|
+
? `${state.version} + malloy ${state.publisherVersion}`
|
|
81
|
+
: state.version;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The paths a `.gitignore` should carry for an install: the skill directories
|
|
85
|
+
* and the rule files, never the user's own files beside them.
|
|
86
|
+
*/
|
|
87
|
+
function skillsGitignoreEntries(state) {
|
|
88
|
+
const entries = new Set();
|
|
89
|
+
for (const file of state.files) {
|
|
90
|
+
const parts = file.split("/");
|
|
91
|
+
if ((file.startsWith(`${exports.SKILLS_DIR}/`) ||
|
|
92
|
+
file.startsWith(`${exports.AGENTS_DIR}/`)) &&
|
|
93
|
+
parts.length >= 3) {
|
|
94
|
+
entries.add(`${parts[0]}/${parts[1]}/${parts[2]}/`);
|
|
95
|
+
}
|
|
96
|
+
else if (file === exports.RULE_FILE_CLAUDE || file === exports.RULE_FILE_CURSOR) {
|
|
97
|
+
entries.add(file);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return [...entries];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A skill name has to be one path segment we would be willing to create.
|
|
104
|
+
*
|
|
105
|
+
* Same rule the Publisher applies to package names (`publisherconfig.ts`'s
|
|
106
|
+
* `SAFE_PACKAGE_NAME`), for the same reason: it is about to become a directory.
|
|
107
|
+
*/
|
|
108
|
+
const SAFE_SKILL_NAME = /^(?!\.\.?$)(?!\.)[A-Za-z0-9._-]+$/;
|
|
109
|
+
function writeSkillFiles(directory, response, host) {
|
|
110
|
+
const all = [...response.auto_discovered, ...response.supporting];
|
|
111
|
+
// `skill:<name>` references in skill text become the path the skill was
|
|
112
|
+
// written to. One tree, so one map; the `.agents/` copy resolves to the
|
|
113
|
+
// `.claude/` paths too — both exist, so no link dangles.
|
|
114
|
+
const pathMap = new Map();
|
|
115
|
+
for (const skill of all) {
|
|
116
|
+
pathMap.set(skill.name, `${exports.SKILLS_DIR}/${skill.name}/SKILL.md`);
|
|
117
|
+
}
|
|
118
|
+
// Whole names only. A substring replace turned `skill:foo-bar` into
|
|
119
|
+
// `.claude/skills/foo/SKILL.md-bar` whenever `foo` came first. Dots only
|
|
120
|
+
// between name characters, so a reference ending a sentence keeps its
|
|
121
|
+
// full stop.
|
|
122
|
+
const resolveRefs = (content) => content.replace(/skill:([A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*)/g, (reference, name) => { var _a; return (_a = pathMap.get(name)) !== null && _a !== void 0 ? _a : reference; });
|
|
123
|
+
// Both halves of the path arrive over the network, and `writeFileAtomic`
|
|
124
|
+
// calls `mkdirSync(..., {recursive: true})` — so a `..` in either one gets
|
|
125
|
+
// its directories created rather than failing. `deleteFiles` below already
|
|
126
|
+
// refuses a path that escapes ("not ours, whatever the state file says");
|
|
127
|
+
// this is the same rule at the write site, where the values are less trusted
|
|
128
|
+
// rather than more. An escaping path is also one the delete guard can then
|
|
129
|
+
// never clean up, so refusing it keeps the two ends agreeing.
|
|
130
|
+
//
|
|
131
|
+
// The boundary is the skill's own directory, not the wired directory. A
|
|
132
|
+
// shorter hop is the one that matters in practice: from
|
|
133
|
+
// `.claude/skills/<name>/`, `../../../.claude/settings.json` lands back
|
|
134
|
+
// inside the tree — on the agent's own settings file — so a check against
|
|
135
|
+
// the tree root would wave it through. A skill's files belong under the
|
|
136
|
+
// skill, and nothing else is ours to write.
|
|
137
|
+
//
|
|
138
|
+
// Not reachable from today's server: `relative_filepath` is server-derived
|
|
139
|
+
// and the manifest comes from a first-party repo. The point is that it stops
|
|
140
|
+
// depending on that.
|
|
141
|
+
const written = [];
|
|
142
|
+
const place = (baseDir) => {
|
|
143
|
+
for (const skill of all) {
|
|
144
|
+
if (!SAFE_SKILL_NAME.test(skill.name)) {
|
|
145
|
+
host.log("warn", `Skipped the skill named "${skill.name}": a skill name has to be a single path segment.`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const skillRoot = path_1.default.resolve(directory, baseDir, skill.name);
|
|
149
|
+
for (const file of skill.files) {
|
|
150
|
+
const full = path_1.default.resolve(skillRoot, file.relative_filepath);
|
|
151
|
+
if (!full.startsWith(skillRoot + path_1.default.sep)) {
|
|
152
|
+
host.log("warn", `Skipped ${skill.name}/${file.relative_filepath}: it resolves outside the skill's own directory.`);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const relative = path_1.default.join(baseDir, skill.name, file.relative_filepath);
|
|
156
|
+
(0, writefile_1.writeFileAtomic)(full, resolveRefs(file.file_contents));
|
|
157
|
+
written.push(relative);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
place(exports.SKILLS_DIR);
|
|
162
|
+
place(exports.AGENTS_DIR);
|
|
163
|
+
return written;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Skill directories under `.claude/skills/` and `.agents/skills/` that a
|
|
167
|
+
* previous install did not write — the scaffolder's set, or the user's own.
|
|
168
|
+
*/
|
|
169
|
+
function foreignSkills(directory, previous) {
|
|
170
|
+
var _a;
|
|
171
|
+
const ours = new Set(((_a = previous === null || previous === void 0 ? void 0 : previous.files) !== null && _a !== void 0 ? _a : [])
|
|
172
|
+
.map((file) => file.split("/"))
|
|
173
|
+
.filter((parts) => parts.length >= 3)
|
|
174
|
+
.map((parts) => `${parts[0]}/${parts[1]}/${parts[2]}`));
|
|
175
|
+
const found = new Set();
|
|
176
|
+
for (const root of [exports.SKILLS_DIR, exports.AGENTS_DIR]) {
|
|
177
|
+
let entries;
|
|
178
|
+
try {
|
|
179
|
+
entries = fs_1.default.readdirSync(path_1.default.join(directory, root), {
|
|
180
|
+
withFileTypes: true,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (_b) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
for (const entry of entries) {
|
|
187
|
+
if (entry.isDirectory() && !ours.has(`${root}/${entry.name}`)) {
|
|
188
|
+
found.add(entry.name);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return [...found].sort();
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Move the named skill directories, from both roots, into
|
|
196
|
+
* `.credible/replaced-skills/<timestamp>/` — returned relative to `directory`.
|
|
197
|
+
* Only ever called after the user chose `replace`.
|
|
198
|
+
*
|
|
199
|
+
* Moved rather than deleted: on a first install "not ours" cannot tell the
|
|
200
|
+
* scaffolder's skills from ones the user wrote, so `replace` is a choice made
|
|
201
|
+
* about files we cannot identify. `.credible/` is gitignored, so the move
|
|
202
|
+
* takes them out of the agent's way without putting them in anyone's commit.
|
|
203
|
+
*/
|
|
204
|
+
function moveForeignSkills(directory, names) {
|
|
205
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
206
|
+
const relative = path_1.default.join(".credible", "replaced-skills", stamp);
|
|
207
|
+
for (const root of [exports.SKILLS_DIR, exports.AGENTS_DIR]) {
|
|
208
|
+
for (const name of names) {
|
|
209
|
+
const source = path_1.default.join(directory, root, name);
|
|
210
|
+
if (!fs_1.default.existsSync(source))
|
|
211
|
+
continue;
|
|
212
|
+
const destination = path_1.default.join(directory, relative, root, name);
|
|
213
|
+
fs_1.default.mkdirSync(path_1.default.dirname(destination), { recursive: true });
|
|
214
|
+
fs_1.default.renameSync(source, destination);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return relative;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The rule file that points an agent at the skills before it starts modeling.
|
|
221
|
+
*
|
|
222
|
+
* Always for Claude Code. For Cursor only when a `.cursor/` directory already
|
|
223
|
+
* exists: the extension can ask the editor which host it is running in, and a
|
|
224
|
+
* CLI cannot, so the directory is the observable signal.
|
|
225
|
+
*/
|
|
226
|
+
function writeRuleFiles(directory, response) {
|
|
227
|
+
const hint = response.trigger_hint || response.description || "";
|
|
228
|
+
if (!hint)
|
|
229
|
+
return [];
|
|
230
|
+
const skillList = response.auto_discovered
|
|
231
|
+
.map((skill) => `\`./${exports.SKILLS_DIR}/${skill.name}/SKILL.md\``)
|
|
232
|
+
.join(", ");
|
|
233
|
+
const rule = `${hint}, first read the workspace skill at ${skillList} and follow its guidance before proceeding.\n`;
|
|
234
|
+
const written = [];
|
|
235
|
+
(0, writefile_1.writeFileAtomic)(path_1.default.join(directory, exports.RULE_FILE_CLAUDE), rule);
|
|
236
|
+
written.push(exports.RULE_FILE_CLAUDE);
|
|
237
|
+
if (fs_1.default.existsSync(path_1.default.join(directory, ".cursor"))) {
|
|
238
|
+
(0, writefile_1.writeFileAtomic)(path_1.default.join(directory, exports.RULE_FILE_CURSOR), `---\nalwaysApply: true\n---\n${rule}`);
|
|
239
|
+
written.push(exports.RULE_FILE_CURSOR);
|
|
240
|
+
}
|
|
241
|
+
return written;
|
|
242
|
+
}
|
|
243
|
+
/** Remove a previous install's files, then any directories that emptied. */
|
|
244
|
+
function deleteFiles(directory, files) {
|
|
245
|
+
const root = path_1.default.resolve(directory);
|
|
246
|
+
const parents = new Set();
|
|
247
|
+
for (const relative of files) {
|
|
248
|
+
const full = path_1.default.resolve(root, relative);
|
|
249
|
+
// A listed path outside the directory is not ours, whatever the state
|
|
250
|
+
// file says.
|
|
251
|
+
if (!full.startsWith(root + path_1.default.sep))
|
|
252
|
+
continue;
|
|
253
|
+
try {
|
|
254
|
+
fs_1.default.unlinkSync(full);
|
|
255
|
+
parents.add(path_1.default.dirname(full));
|
|
256
|
+
}
|
|
257
|
+
catch (_a) {
|
|
258
|
+
// Already gone. The point is that it is not there afterwards.
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
for (const dir of [...parents].sort((a, b) => b.length - a.length)) {
|
|
262
|
+
removeEmptyDirsUpTo(dir, root);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function removeEmptyDirsUpTo(dir, root) {
|
|
266
|
+
let current = dir;
|
|
267
|
+
while (current !== root && current.startsWith(root + path_1.default.sep)) {
|
|
268
|
+
try {
|
|
269
|
+
if (fs_1.default.readdirSync(current).length > 0)
|
|
270
|
+
return;
|
|
271
|
+
fs_1.default.rmdirSync(current);
|
|
272
|
+
}
|
|
273
|
+
catch (_a) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
current = path_1.default.dirname(current);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/setup-core/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const chai_1 = require("chai");
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const os_1 = __importDefault(require("os"));
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
19
|
+
const skills_1 = require("./skills");
|
|
20
|
+
function quietHost() {
|
|
21
|
+
const logs = [];
|
|
22
|
+
return {
|
|
23
|
+
logs,
|
|
24
|
+
select(_m, choices) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
return choices[0].value;
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
selectMany() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
return [];
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
confirm() {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
return true;
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
log(level, message) {
|
|
40
|
+
logs.push(`${level}: ${message}`);
|
|
41
|
+
},
|
|
42
|
+
write() { },
|
|
43
|
+
openUrl() {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** A manifest with one auto-discovered skill citing one supporting skill. */
|
|
49
|
+
const response = {
|
|
50
|
+
manifest: "modeling-ide",
|
|
51
|
+
version: "v1.2.0",
|
|
52
|
+
trigger_hint: "When modeling data with Malloy",
|
|
53
|
+
auto_discovered: [
|
|
54
|
+
{
|
|
55
|
+
name: "malloy-modeling",
|
|
56
|
+
files: [
|
|
57
|
+
{
|
|
58
|
+
relative_filepath: "SKILL.md",
|
|
59
|
+
file_contents: "# Modeling\nSee skill:gotchas-modeling first.",
|
|
60
|
+
},
|
|
61
|
+
{ relative_filepath: "reference/joins.md", file_contents: "joins" },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
supporting: [
|
|
66
|
+
{
|
|
67
|
+
name: "gotchas-modeling",
|
|
68
|
+
files: [{ relative_filepath: "SKILL.md", file_contents: "# Gotchas" }],
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
describe("installing skills", () => {
|
|
73
|
+
let workDir;
|
|
74
|
+
const read = (relative) => fs_1.default.readFileSync(path_1.default.join(workDir, relative), "utf-8");
|
|
75
|
+
const exists = (relative) => fs_1.default.existsSync(path_1.default.join(workDir, relative));
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
workDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "skills-"));
|
|
78
|
+
});
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
fs_1.default.rmSync(workDir, { recursive: true, force: true });
|
|
81
|
+
});
|
|
82
|
+
it("places every skill — auto-discovered and supporting alike — under .claude/skills, plus the cross-tool copy", () => {
|
|
83
|
+
// No `.credible/skills/` tier: the extension's supporting placement was
|
|
84
|
+
// installed and never read, since agents did not follow `skill:` links.
|
|
85
|
+
const result = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
86
|
+
(0, chai_1.expect)(result.action).to.equal("installed");
|
|
87
|
+
(0, chai_1.expect)(result.state.files.sort()).to.eql([
|
|
88
|
+
".agents/skills/gotchas-modeling/SKILL.md",
|
|
89
|
+
".agents/skills/malloy-modeling/SKILL.md",
|
|
90
|
+
".agents/skills/malloy-modeling/reference/joins.md",
|
|
91
|
+
".claude/rules/credible-modeling.md",
|
|
92
|
+
".claude/skills/gotchas-modeling/SKILL.md",
|
|
93
|
+
".claude/skills/malloy-modeling/SKILL.md",
|
|
94
|
+
".claude/skills/malloy-modeling/reference/joins.md",
|
|
95
|
+
]);
|
|
96
|
+
for (const file of result.state.files)
|
|
97
|
+
(0, chai_1.expect)(exists(file)).to.equal(true);
|
|
98
|
+
(0, chai_1.expect)(exists(".credible/skills")).to.equal(false);
|
|
99
|
+
});
|
|
100
|
+
it("rewrites skill: references to the path the skill was written to", () => {
|
|
101
|
+
(0, skills_1.installSkills)(workDir, response, quietHost());
|
|
102
|
+
(0, chai_1.expect)(read(".claude/skills/malloy-modeling/SKILL.md")).to.contain("See .claude/skills/gotchas-modeling/SKILL.md first.");
|
|
103
|
+
// The .agents copy points into Claude's tree too — both exist, so no
|
|
104
|
+
// link dangles.
|
|
105
|
+
(0, chai_1.expect)(read(".agents/skills/malloy-modeling/SKILL.md")).to.contain(".claude/skills/gotchas-modeling/SKILL.md");
|
|
106
|
+
});
|
|
107
|
+
// A substring replace rewrote `skill:foo-bar` with `foo`'s path whenever
|
|
108
|
+
// `foo` came first in the manifest.
|
|
109
|
+
it("rewrites whole skill names only, and keeps a reference's full stop", () => {
|
|
110
|
+
(0, skills_1.installSkills)(workDir, Object.assign(Object.assign({}, response), { auto_discovered: [
|
|
111
|
+
{
|
|
112
|
+
name: "foo",
|
|
113
|
+
files: [
|
|
114
|
+
{
|
|
115
|
+
relative_filepath: "SKILL.md",
|
|
116
|
+
file_contents: "Then skill:foo-bar, and skill:missing. End with skill:foo.",
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{ name: "foo-bar", files: [] },
|
|
121
|
+
], supporting: [] }), quietHost());
|
|
122
|
+
(0, chai_1.expect)(read(".claude/skills/foo/SKILL.md")).to.equal("Then .claude/skills/foo-bar/SKILL.md, and skill:missing. End with .claude/skills/foo/SKILL.md.");
|
|
123
|
+
});
|
|
124
|
+
it("writes the Claude rule from the trigger hint, naming every auto-discovered skill", () => {
|
|
125
|
+
(0, skills_1.installSkills)(workDir, response, quietHost());
|
|
126
|
+
(0, chai_1.expect)(read(".claude/rules/credible-modeling.md")).to.equal("When modeling data with Malloy, first read the workspace skill at `./.claude/skills/malloy-modeling/SKILL.md` and follow its guidance before proceeding.\n");
|
|
127
|
+
});
|
|
128
|
+
it("writes the Cursor rule only when a .cursor directory already exists", () => {
|
|
129
|
+
const without = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
130
|
+
(0, chai_1.expect)(without.state.files).to.not.include(".cursor/rules/credible-modeling.mdc");
|
|
131
|
+
fs_1.default.mkdirSync(path_1.default.join(workDir, ".cursor"));
|
|
132
|
+
const withCursor = (0, skills_1.installSkills)(workDir, Object.assign(Object.assign({}, response), { version: "v1.3.0" }), quietHost(), without.state);
|
|
133
|
+
(0, chai_1.expect)(withCursor.state.files).to.include(".cursor/rules/credible-modeling.mdc");
|
|
134
|
+
(0, chai_1.expect)(read(".cursor/rules/credible-modeling.mdc")).to.contain("alwaysApply: true");
|
|
135
|
+
});
|
|
136
|
+
it("is a no-op on the same version with every file present", () => {
|
|
137
|
+
const first = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
138
|
+
const before = fs_1.default.statSync(path_1.default.join(workDir, ".claude/skills/malloy-modeling/SKILL.md")).mtimeMs;
|
|
139
|
+
const again = (0, skills_1.installSkills)(workDir, response, quietHost(), first.state);
|
|
140
|
+
(0, chai_1.expect)(again.action).to.equal("current");
|
|
141
|
+
(0, chai_1.expect)(fs_1.default.statSync(path_1.default.join(workDir, ".claude/skills/malloy-modeling/SKILL.md")).mtimeMs).to.equal(before);
|
|
142
|
+
});
|
|
143
|
+
// The `malloy-*` skills come from `@malloy-publisher/skills` at
|
|
144
|
+
// `skills_version`, which moves without the agent-skills tag. Comparing the
|
|
145
|
+
// tag alone left every wired directory on the old `malloy-*` skills.
|
|
146
|
+
it("re-installs when only the malloy skills version moved", () => {
|
|
147
|
+
const first = (0, skills_1.installSkills)(workDir, Object.assign(Object.assign({}, response), { publisher_skills_version: "0.1.30" }), quietHost());
|
|
148
|
+
(0, chai_1.expect)(first.state.publisherVersion).to.equal("0.1.30");
|
|
149
|
+
const again = (0, skills_1.installSkills)(workDir, Object.assign(Object.assign({}, response), { publisher_skills_version: "0.1.31" }), quietHost(), first.state);
|
|
150
|
+
(0, chai_1.expect)(again.action).to.equal("updated");
|
|
151
|
+
(0, chai_1.expect)(again.state.publisherVersion).to.equal("0.1.31");
|
|
152
|
+
});
|
|
153
|
+
it("re-installs when a listed file has gone missing", () => {
|
|
154
|
+
const first = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
155
|
+
fs_1.default.unlinkSync(path_1.default.join(workDir, ".claude/skills/malloy-modeling/SKILL.md"));
|
|
156
|
+
const again = (0, skills_1.installSkills)(workDir, response, quietHost(), first.state);
|
|
157
|
+
(0, chai_1.expect)(again.action).to.equal("updated");
|
|
158
|
+
(0, chai_1.expect)(exists(".claude/skills/malloy-modeling/SKILL.md")).to.equal(true);
|
|
159
|
+
});
|
|
160
|
+
it("removes a previous version's files that the new one no longer has, and the directories they emptied", () => {
|
|
161
|
+
const first = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
162
|
+
const slimmer = Object.assign(Object.assign({}, response), { version: "v2.0.0", auto_discovered: [
|
|
163
|
+
{
|
|
164
|
+
name: "malloy-modeling",
|
|
165
|
+
files: [{ relative_filepath: "SKILL.md", file_contents: "v2" }],
|
|
166
|
+
},
|
|
167
|
+
] });
|
|
168
|
+
(0, skills_1.installSkills)(workDir, slimmer, quietHost(), first.state);
|
|
169
|
+
(0, chai_1.expect)(exists(".claude/skills/malloy-modeling/reference/joins.md")).to.equal(false);
|
|
170
|
+
(0, chai_1.expect)(exists(".claude/skills/malloy-modeling/reference")).to.equal(false);
|
|
171
|
+
(0, chai_1.expect)(read(".claude/skills/malloy-modeling/SKILL.md")).to.equal("v2");
|
|
172
|
+
});
|
|
173
|
+
it("never touches a file it did not write", () => {
|
|
174
|
+
const first = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
175
|
+
const mine = path_1.default.join(workDir, ".claude/skills/my-own/SKILL.md");
|
|
176
|
+
fs_1.default.mkdirSync(path_1.default.dirname(mine), { recursive: true });
|
|
177
|
+
fs_1.default.writeFileSync(mine, "mine");
|
|
178
|
+
(0, skills_1.installSkills)(workDir, Object.assign(Object.assign({}, response), { version: "v9" }), quietHost(), first.state);
|
|
179
|
+
(0, chai_1.expect)(fs_1.default.readFileSync(mine, "utf-8")).to.equal("mine");
|
|
180
|
+
});
|
|
181
|
+
it("ignores a state entry that points outside the directory", () => {
|
|
182
|
+
// Its own private directory, not a predictable name in the shared temp
|
|
183
|
+
// dir: the point is a path outside `workDir`, and mkdtemp gives one.
|
|
184
|
+
const outsideDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "skills-out-"));
|
|
185
|
+
const outside = path_1.default.join(outsideDir, "keep.md");
|
|
186
|
+
fs_1.default.writeFileSync(outside, "keep");
|
|
187
|
+
try {
|
|
188
|
+
(0, skills_1.installSkills)(workDir, response, quietHost(), {
|
|
189
|
+
manifest: "modeling-ide",
|
|
190
|
+
version: "v0",
|
|
191
|
+
files: [path_1.default.relative(workDir, outside)],
|
|
192
|
+
});
|
|
193
|
+
(0, chai_1.expect)(fs_1.default.existsSync(outside)).to.equal(true);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
fs_1.default.rmSync(outsideDir, { recursive: true, force: true });
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
// The mirror of "ignores a state entry that points outside the directory",
|
|
200
|
+
// at the write site. That guard is on locally-stored state; these values
|
|
201
|
+
// arrive over the network, so they are the less trusted of the two — and
|
|
202
|
+
// `writeFileAtomic` mkdirs recursively, so an escaping path gets its
|
|
203
|
+
// directories created rather than failing. A path that escapes is also one
|
|
204
|
+
// the delete guard can then never clean up.
|
|
205
|
+
describe("paths that escape the directory", () => {
|
|
206
|
+
const outside = (skill) => ({
|
|
207
|
+
manifest: "modeling-ide",
|
|
208
|
+
version: "v1",
|
|
209
|
+
trigger_hint: "x",
|
|
210
|
+
auto_discovered: [skill],
|
|
211
|
+
supporting: [],
|
|
212
|
+
});
|
|
213
|
+
// The short hop, and the reason the boundary is the skill's directory
|
|
214
|
+
// rather than the wired one: three levels up from
|
|
215
|
+
// `.claude/skills/<name>/` lands back *inside* the tree, on the settings
|
|
216
|
+
// file of the agent this directory was wired for. A check against the
|
|
217
|
+
// tree root would wave it through.
|
|
218
|
+
it("refuses a relative_filepath that climbs out of the skill", () => {
|
|
219
|
+
const host = quietHost();
|
|
220
|
+
const result = (0, skills_1.installSkills)(workDir, outside({
|
|
221
|
+
name: "malloy-modeling",
|
|
222
|
+
files: [
|
|
223
|
+
{
|
|
224
|
+
relative_filepath: "../../../.claude/settings.json",
|
|
225
|
+
file_contents: "owned",
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
}), host);
|
|
229
|
+
(0, chai_1.expect)(exists(".claude/settings.json")).to.equal(false);
|
|
230
|
+
(0, chai_1.expect)(result.state.files).to.not.include(".claude/settings.json");
|
|
231
|
+
(0, chai_1.expect)(host.logs.join("\n")).to.contain("resolves outside the skill's own directory");
|
|
232
|
+
});
|
|
233
|
+
it("refuses one that leaves the wired directory altogether", () => {
|
|
234
|
+
// Its own parent, so "did anything land above the directory?" cannot
|
|
235
|
+
// be answered by a file some other test left in the shared temp dir.
|
|
236
|
+
const parent = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "skills-esc-"));
|
|
237
|
+
const wired = path_1.default.join(parent, "models");
|
|
238
|
+
fs_1.default.mkdirSync(wired);
|
|
239
|
+
try {
|
|
240
|
+
(0, skills_1.installSkills)(wired, outside({
|
|
241
|
+
name: "malloy-modeling",
|
|
242
|
+
files: [
|
|
243
|
+
{
|
|
244
|
+
relative_filepath: "../../../../owned.md",
|
|
245
|
+
file_contents: "owned",
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
}), quietHost());
|
|
249
|
+
(0, chai_1.expect)(fs_1.default.readdirSync(parent)).to.eql(["models"]);
|
|
250
|
+
}
|
|
251
|
+
finally {
|
|
252
|
+
fs_1.default.rmSync(parent, { recursive: true, force: true });
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
it("refuses a skill name that is not a single path segment", () => {
|
|
256
|
+
const host = quietHost();
|
|
257
|
+
for (const name of ["../../../../.ssh", "..", ".", ".hidden", "a/b"]) {
|
|
258
|
+
const result = (0, skills_1.installSkills)(workDir, outside({
|
|
259
|
+
name,
|
|
260
|
+
files: [
|
|
261
|
+
{
|
|
262
|
+
relative_filepath: "authorized_keys",
|
|
263
|
+
file_contents: "owned",
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
}), host);
|
|
267
|
+
// The rule files are still written; no skill file is.
|
|
268
|
+
(0, chai_1.expect)(result.state.files.filter((f) => f.includes("authorized_keys")), name).to.eql([]);
|
|
269
|
+
}
|
|
270
|
+
(0, chai_1.expect)(fs_1.default.existsSync(path_1.default.join(workDir, "..", ".ssh"))).to.equal(false);
|
|
271
|
+
(0, chai_1.expect)(host.logs.join("\n")).to.contain("single path segment");
|
|
272
|
+
});
|
|
273
|
+
it("still writes the ordinary names beside a refused one", () => {
|
|
274
|
+
const host = quietHost();
|
|
275
|
+
const result = (0, skills_1.installSkills)(workDir, Object.assign(Object.assign({}, response), { supporting: [
|
|
276
|
+
{
|
|
277
|
+
name: "..",
|
|
278
|
+
files: [
|
|
279
|
+
{
|
|
280
|
+
relative_filepath: "../../.zshrc",
|
|
281
|
+
file_contents: "owned",
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
},
|
|
285
|
+
] }), host);
|
|
286
|
+
(0, chai_1.expect)(exists(".claude/skills/malloy-modeling/SKILL.md")).to.equal(true);
|
|
287
|
+
(0, chai_1.expect)(result.state.files).to.not.include("../../.zshrc");
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
it("lists every skill directory and the rule file for .gitignore", () => {
|
|
291
|
+
const { state } = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
292
|
+
(0, chai_1.expect)((0, skills_1.skillsGitignoreEntries)(state)).to.eql([
|
|
293
|
+
".claude/skills/malloy-modeling/",
|
|
294
|
+
".claude/skills/gotchas-modeling/",
|
|
295
|
+
".agents/skills/malloy-modeling/",
|
|
296
|
+
".agents/skills/gotchas-modeling/",
|
|
297
|
+
".claude/rules/credible-modeling.md",
|
|
298
|
+
]);
|
|
299
|
+
});
|
|
300
|
+
describe("skills that are not ours", () => {
|
|
301
|
+
function plant(name, root = ".claude/skills") {
|
|
302
|
+
const dir = path_1.default.join(workDir, root, name);
|
|
303
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
304
|
+
fs_1.default.writeFileSync(path_1.default.join(dir, "SKILL.md"), name);
|
|
305
|
+
}
|
|
306
|
+
it("finds skill directories a previous install did not write, in either root", () => {
|
|
307
|
+
plant("malloy-getting-started");
|
|
308
|
+
plant("eval-loop", ".agents/skills");
|
|
309
|
+
const { state } = (0, skills_1.installSkills)(workDir, response, quietHost());
|
|
310
|
+
(0, chai_1.expect)((0, skills_1.foreignSkills)(workDir, state)).to.eql([
|
|
311
|
+
"eval-loop",
|
|
312
|
+
"malloy-getting-started",
|
|
313
|
+
]);
|
|
314
|
+
});
|
|
315
|
+
it("with no previous install, everything present is foreign", () => {
|
|
316
|
+
plant("malloy-modeling");
|
|
317
|
+
(0, chai_1.expect)((0, skills_1.foreignSkills)(workDir)).to.eql(["malloy-modeling"]);
|
|
318
|
+
});
|
|
319
|
+
it("moves exactly the named directories, from both roots, aside and nothing else", () => {
|
|
320
|
+
plant("malloy-getting-started");
|
|
321
|
+
plant("malloy-getting-started", ".agents/skills");
|
|
322
|
+
plant("mine");
|
|
323
|
+
const movedTo = (0, skills_1.moveForeignSkills)(workDir, ["malloy-getting-started"]);
|
|
324
|
+
(0, chai_1.expect)(exists(".claude/skills/malloy-getting-started")).to.equal(false);
|
|
325
|
+
(0, chai_1.expect)(exists(".agents/skills/malloy-getting-started")).to.equal(false);
|
|
326
|
+
(0, chai_1.expect)(movedTo).to.match(/^\.credible\/replaced-skills\/[^/]+$/);
|
|
327
|
+
// Moved, not deleted: on a first install these may be the user's own.
|
|
328
|
+
(0, chai_1.expect)(read(`${movedTo}/.claude/skills/malloy-getting-started/SKILL.md`)).to.equal("malloy-getting-started");
|
|
329
|
+
(0, chai_1.expect)(read(`${movedTo}/.agents/skills/malloy-getting-started/SKILL.md`)).to.equal("malloy-getting-started");
|
|
330
|
+
(0, chai_1.expect)(read(".claude/skills/mine/SKILL.md")).to.equal("mine");
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
//# sourceMappingURL=skills.spec.js.map
|