windmill-cli 1.598.0 → 1.599.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_create_walk_entry.js +2 -2
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_is_same_path.js +1 -1
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_is_subdir.js +2 -2
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_to_path_string.js +1 -1
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/copy.js +3 -3
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/empty_dir.js +1 -1
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_file.js +1 -1
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_link.js +1 -1
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_symlink.js +2 -2
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/expand_glob.js +9 -7
- package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/walk.js +1 -1
- package/esm/deps/jsr.io/@std/log/0.224.14/rotating_file_handler.js +1 -1
- package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/glob_to_reg_exp.js +2 -1
- package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/relative.js +1 -1
- package/esm/deps.js +3 -3
- package/esm/gen/core/OpenAPI.js +1 -1
- package/esm/gen/services.gen.js +16 -0
- package/esm/src/commands/app/app.js +4 -0
- package/esm/src/commands/app/dev.js +488 -11
- package/esm/src/commands/app/generate_agents.js +214 -0
- package/esm/src/commands/app/new.js +532 -0
- package/esm/src/commands/app/raw_apps.js +74 -10
- package/esm/src/commands/sync/sync.js +345 -1
- package/esm/src/main.js +1 -1
- package/package.json +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_create_walk_entry.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_get_file_info_type.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_is_same_path.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_is_subdir.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_to_path_string.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/copy.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/empty_dir.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_dir.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_file.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_link.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_symlink.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/eol.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/exists.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/expand_glob.d.ts +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/expand_glob.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/mod.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/move.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/walk.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/assert_path.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/basename.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/common.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/constants.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/dirname.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/format.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/from_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/glob_to_reg_exp.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/normalize.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/normalize_string.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/relative.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/strip_trailing_separators.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/to_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/basename.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/common.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/constants.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/dirname.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/extname.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/format.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/from_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/glob_to_regexp.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/is_absolute.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/is_glob.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/join.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/join_globs.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/mod.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/normalize.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/normalize_glob.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/parse.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/_util.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/basename.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/constants.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/dirname.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/extname.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/format.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/from_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/glob_to_regexp.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/is_absolute.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/join.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/join_globs.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/normalize.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/normalize_glob.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/parse.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/relative.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/resolve.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/to_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/to_namespaced_path.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/relative.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/resolve.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/to_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/to_namespaced_path.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/types.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/_util.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/basename.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/constants.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/dirname.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/extname.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/format.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/from_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/glob_to_regexp.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/is_absolute.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/join.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/join_globs.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/normalize.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/normalize_glob.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/parse.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/relative.d.ts +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/relative.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/resolve.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/to_file_url.d.ts.map +1 -1
- package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/to_namespaced_path.d.ts.map +1 -1
- package/types/deps.d.ts +3 -3
- package/types/gen/services.gen.d.ts +9 -1
- package/types/gen/services.gen.d.ts.map +1 -1
- package/types/gen/types.gen.d.ts +18 -0
- package/types/gen/types.gen.d.ts.map +1 -1
- package/types/src/commands/app/app.d.ts.map +1 -1
- package/types/src/commands/app/dev.d.ts.map +1 -1
- package/types/src/commands/app/generate_agents.d.ts +15 -0
- package/types/src/commands/app/generate_agents.d.ts.map +1 -0
- package/types/src/commands/app/new.d.ts +10 -0
- package/types/src/commands/app/new.d.ts.map +1 -0
- package/types/src/commands/app/raw_apps.d.ts +6 -3
- package/types/src/commands/app/raw_apps.d.ts.map +1 -1
- package/types/src/commands/sync/sync.d.ts +18 -0
- package/types/src/commands/sync/sync.d.ts.map +1 -1
- package/types/src/main.d.ts +1 -1
- package/types/windmill-utils-internal/src/gen/types.gen.d.ts +18 -0
- package/types/windmill-utils-internal/src/gen/types.gen.d.ts.map +1 -1
- /package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_get_file_info_type.js +0 -0
- /package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_dir.js +0 -0
- /package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/eol.js +0 -0
- /package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/exists.js +0 -0
- /package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/mod.js +0 -0
- /package/esm/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/move.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/assert_path.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/basename.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/common.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/constants.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/dirname.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/format.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/from_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/normalize.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/normalize_string.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/relative.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/strip_trailing_separators.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/to_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/basename.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/common.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/constants.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/dirname.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/extname.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/format.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/from_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/glob_to_regexp.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/is_absolute.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/is_glob.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/join.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/join_globs.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/mod.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/normalize.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/normalize_glob.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/parse.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/_util.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/basename.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/constants.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/dirname.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/extname.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/format.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/from_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/glob_to_regexp.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/is_absolute.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/join.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/join_globs.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/normalize.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/normalize_glob.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/parse.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/relative.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/resolve.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/to_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/to_namespaced_path.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/relative.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/resolve.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/to_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/to_namespaced_path.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/types.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/_util.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/basename.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/constants.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/dirname.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/extname.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/format.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/from_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/glob_to_regexp.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/is_absolute.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/join.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/join_globs.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/normalize.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/normalize_glob.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/parse.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/resolve.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/to_file_url.js +0 -0
- /package/esm/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/to_namespaced_path.js +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_create_walk_entry.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_get_file_info_type.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_is_same_path.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_is_subdir.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/_to_path_string.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/copy.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/empty_dir.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_dir.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_file.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_link.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/ensure_symlink.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/eol.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/exists.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/mod.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/move.d.ts +0 -0
- /package/types/deps/jsr.io/@std/fs/{1.0.20 → 1.0.21}/walk.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/assert_path.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/basename.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/common.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/constants.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/dirname.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/format.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/from_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/glob_to_reg_exp.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/normalize.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/normalize_string.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/relative.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/strip_trailing_separators.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/_common/to_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/basename.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/common.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/constants.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/dirname.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/extname.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/format.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/from_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/glob_to_regexp.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/is_absolute.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/is_glob.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/join.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/join_globs.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/mod.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/normalize.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/normalize_glob.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/parse.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/_util.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/basename.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/constants.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/dirname.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/extname.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/format.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/from_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/glob_to_regexp.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/is_absolute.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/join.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/join_globs.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/normalize.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/normalize_glob.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/parse.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/relative.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/resolve.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/to_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/posix/to_namespaced_path.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/relative.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/resolve.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/to_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/to_namespaced_path.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/types.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/_util.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/basename.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/constants.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/dirname.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/extname.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/format.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/from_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/glob_to_regexp.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/is_absolute.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/join.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/join_globs.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/normalize.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/normalize_glob.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/parse.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/resolve.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/to_file_url.d.ts +0 -0
- /package/types/deps/jsr.io/@std/path/{1.1.3 → 1.1.4}/windows/to_namespaced_path.d.ts +0 -0
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
|
+
import { colors, Command, Confirm, ensureDir, Input, log, Select, yamlStringify, } from "../../../deps.js";
|
|
3
|
+
import { generateAgentsDocumentation, generateDatatablesDocumentation, yamlOptions } from "../sync/sync.js";
|
|
4
|
+
import { resolveWorkspace } from "../../core/context.js";
|
|
5
|
+
import { requireLogin } from "../../core/auth.js";
|
|
6
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
// Framework templates - adapted from frontend/src/routes/(root)/(logged)/apps_raw/add/templates.ts
|
|
9
|
+
const reactIndex = `
|
|
10
|
+
import React from 'react'
|
|
11
|
+
|
|
12
|
+
import { createRoot } from 'react-dom/client'
|
|
13
|
+
import App from './App'
|
|
14
|
+
|
|
15
|
+
const root = createRoot(document.getElementById('root')!);
|
|
16
|
+
root.render(<App/>);
|
|
17
|
+
`;
|
|
18
|
+
const appTsx = `import React, { useState } from 'react'
|
|
19
|
+
import { backend } from './wmill'
|
|
20
|
+
import './index.css'
|
|
21
|
+
|
|
22
|
+
const App = () => {
|
|
23
|
+
const [value, setValue] = useState(undefined as string | undefined)
|
|
24
|
+
const [loading, setLoading] = useState(false)
|
|
25
|
+
|
|
26
|
+
async function runA() {
|
|
27
|
+
setLoading(true)
|
|
28
|
+
try {
|
|
29
|
+
setValue(await backend.a({ x: 42 }))
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.error()
|
|
32
|
+
}
|
|
33
|
+
setLoading(false)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return <div style={{ width: "100%" }}>
|
|
37
|
+
<h1>hello world</h1>
|
|
38
|
+
|
|
39
|
+
<button style={{ marginTop: "2px" }} onClick={runA}>Run 'a'</button>
|
|
40
|
+
|
|
41
|
+
<div style={{ marginTop: "20px", width: '250px' }} className='myclass'>
|
|
42
|
+
{loading ? 'Loading ...' : value ?? 'Click button to see value here'}
|
|
43
|
+
</div>
|
|
44
|
+
</div>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default App;
|
|
48
|
+
`;
|
|
49
|
+
const appSvelte = `<style>
|
|
50
|
+
h1 {
|
|
51
|
+
font-size: 1.5rem;
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
54
|
+
|
|
55
|
+
<main>
|
|
56
|
+
<h1>Hello {name}</h1>
|
|
57
|
+
</main>
|
|
58
|
+
|
|
59
|
+
<script>
|
|
60
|
+
let name = 'world';
|
|
61
|
+
</script>`;
|
|
62
|
+
const indexSvelte = `
|
|
63
|
+
import { mount } from 'svelte';
|
|
64
|
+
import App from './App.svelte'
|
|
65
|
+
import './index.css'
|
|
66
|
+
|
|
67
|
+
const app = mount(App, { target: document.getElementById("root")! });
|
|
68
|
+
|
|
69
|
+
export default app;
|
|
70
|
+
`;
|
|
71
|
+
const appVue = `<template>
|
|
72
|
+
<h1>Hello {{ msg }}</h1>
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
<script setup>
|
|
76
|
+
import { ref } from 'vue';
|
|
77
|
+
const msg = ref('world');
|
|
78
|
+
</script>`;
|
|
79
|
+
const indexVue = `import { createApp } from 'vue'
|
|
80
|
+
import App from './App.vue'
|
|
81
|
+
import "./index.css";
|
|
82
|
+
|
|
83
|
+
createApp(App).mount('#root')`;
|
|
84
|
+
const indexCss = `.myclass {
|
|
85
|
+
border: 1px solid gray;
|
|
86
|
+
padding: 2px;
|
|
87
|
+
}`;
|
|
88
|
+
const templates = {
|
|
89
|
+
react19: {
|
|
90
|
+
name: "React 19",
|
|
91
|
+
files: {
|
|
92
|
+
"/index.tsx": reactIndex,
|
|
93
|
+
"/App.tsx": appTsx,
|
|
94
|
+
"/index.css": indexCss,
|
|
95
|
+
"/package.json": `{
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"react": "19.0.0",
|
|
98
|
+
"react-dom": "19.0.0",
|
|
99
|
+
"windmill-client": "^1"
|
|
100
|
+
},
|
|
101
|
+
"devDependencies": {
|
|
102
|
+
"@types/react-dom": "^19.0.0",
|
|
103
|
+
"@types/react": "^19.0.0"
|
|
104
|
+
}
|
|
105
|
+
}`,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
react18: {
|
|
109
|
+
name: "React 18",
|
|
110
|
+
files: {
|
|
111
|
+
"/index.tsx": reactIndex,
|
|
112
|
+
"/App.tsx": appTsx,
|
|
113
|
+
"/index.css": indexCss,
|
|
114
|
+
"/package.json": `{
|
|
115
|
+
"dependencies": {
|
|
116
|
+
"react": "18.3.1",
|
|
117
|
+
"react-dom": "18.3.1",
|
|
118
|
+
"windmill-client": "^1"
|
|
119
|
+
},
|
|
120
|
+
"devDependencies": {
|
|
121
|
+
"@types/react-dom": "^19.0.0",
|
|
122
|
+
"@types/react": "^19.0.0"
|
|
123
|
+
}
|
|
124
|
+
}`,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
svelte5: {
|
|
128
|
+
name: "Svelte 5",
|
|
129
|
+
files: {
|
|
130
|
+
"/index.ts": indexSvelte,
|
|
131
|
+
"/App.svelte": appSvelte,
|
|
132
|
+
"/index.css": indexCss,
|
|
133
|
+
"/package.json": `{
|
|
134
|
+
"dependencies": {
|
|
135
|
+
"svelte": "5.45.2",
|
|
136
|
+
"windmill-client": "^1"
|
|
137
|
+
}
|
|
138
|
+
}`,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
vue: {
|
|
142
|
+
name: "Vue 3",
|
|
143
|
+
files: {
|
|
144
|
+
"/index.ts": indexVue,
|
|
145
|
+
"/App.vue": appVue,
|
|
146
|
+
"/index.css": indexCss,
|
|
147
|
+
"/package.json": `{
|
|
148
|
+
"dependencies": {
|
|
149
|
+
"core-js": "3.26.1",
|
|
150
|
+
"vue": "3.5.13",
|
|
151
|
+
"windmill-client": "^1"
|
|
152
|
+
}
|
|
153
|
+
}`,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Validates that a path follows the Windmill app path conventions:
|
|
159
|
+
* - Must start with u/ (user) or f/ (folder)
|
|
160
|
+
* - Cannot contain dots
|
|
161
|
+
* - Can only contain alphanumeric characters, underscores, hyphens, and slashes
|
|
162
|
+
*/
|
|
163
|
+
function validateAppPath(appPath) {
|
|
164
|
+
if (!appPath.startsWith("u/") && !appPath.startsWith("f/")) {
|
|
165
|
+
return {
|
|
166
|
+
valid: false,
|
|
167
|
+
error: "Path must start with 'u/' (user) or 'f/' (folder)",
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (appPath.includes(".")) {
|
|
171
|
+
return {
|
|
172
|
+
valid: false,
|
|
173
|
+
error: "Path cannot contain dots (.)",
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// Check for valid characters: alphanumeric, underscore, hyphen, and slash
|
|
177
|
+
const validPathRegex = /^[a-zA-Z0-9_\-/]+$/;
|
|
178
|
+
if (!validPathRegex.test(appPath)) {
|
|
179
|
+
return {
|
|
180
|
+
valid: false,
|
|
181
|
+
error: "Path can only contain alphanumeric characters, underscores, hyphens, and slashes",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// Check that path has at least two segments (prefix/name)
|
|
185
|
+
const segments = appPath.split("/").filter((s) => s.length > 0);
|
|
186
|
+
if (segments.length < 2) {
|
|
187
|
+
return {
|
|
188
|
+
valid: false,
|
|
189
|
+
error: "Path must have at least two segments (e.g., u/username/app_name)",
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return { valid: true };
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Generate a unique schema name (appX where X is first unused number)
|
|
196
|
+
*/
|
|
197
|
+
function generateUniqueSchemaName(existingSchemas) {
|
|
198
|
+
let num = 1;
|
|
199
|
+
while (existingSchemas.includes(`app${num}`)) {
|
|
200
|
+
num++;
|
|
201
|
+
}
|
|
202
|
+
return `app${num}`;
|
|
203
|
+
}
|
|
204
|
+
async function newApp(opts) {
|
|
205
|
+
log.info(colors.bold.cyan("Create a new Windmill Raw App"));
|
|
206
|
+
log.info("");
|
|
207
|
+
// Resolve workspace and authenticate
|
|
208
|
+
const workspace = await resolveWorkspace(opts);
|
|
209
|
+
await requireLogin(opts);
|
|
210
|
+
const workspaceId = workspace.workspaceId;
|
|
211
|
+
// Fetch available folders for autocompletion
|
|
212
|
+
let folderNames = [];
|
|
213
|
+
try {
|
|
214
|
+
folderNames = await wmill.listFolderNames({ workspace: workspaceId });
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Ignore errors fetching folders
|
|
218
|
+
}
|
|
219
|
+
// Fetch available datatables
|
|
220
|
+
let datatables = [];
|
|
221
|
+
let datatableSchemas = new Map();
|
|
222
|
+
try {
|
|
223
|
+
log.info(colors.gray("Fetching available datatables..."));
|
|
224
|
+
datatables = await wmill.listDataTables({ workspace: workspaceId });
|
|
225
|
+
if (datatables.length > 0) {
|
|
226
|
+
// Fetch schemas for all datatables
|
|
227
|
+
const schemaData = await wmill.listDataTableSchemas({
|
|
228
|
+
workspace: workspaceId,
|
|
229
|
+
});
|
|
230
|
+
for (const dt of schemaData) {
|
|
231
|
+
if (dt.schemas && !dt.error) {
|
|
232
|
+
const schemaNames = Object.keys(dt.schemas);
|
|
233
|
+
datatableSchemas.set(dt.datatable_name, schemaNames);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
240
|
+
log.warn(colors.yellow(`Could not fetch datatables: ${errorMessage}`));
|
|
241
|
+
}
|
|
242
|
+
// Ask for summary
|
|
243
|
+
const summary = await Input.prompt({
|
|
244
|
+
message: "App summary (short description):",
|
|
245
|
+
minLength: 1,
|
|
246
|
+
validate: (value) => {
|
|
247
|
+
if (value.trim().length === 0) {
|
|
248
|
+
return "Summary cannot be empty";
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
// Build suggestions for path autocompletion
|
|
254
|
+
const buildPathSuggestions = (input) => {
|
|
255
|
+
const suggestions = [];
|
|
256
|
+
// If empty or very short, suggest prefixes
|
|
257
|
+
if (input.length < 2) {
|
|
258
|
+
suggestions.push("f/", "u/");
|
|
259
|
+
}
|
|
260
|
+
// If starts with f/, suggest folders
|
|
261
|
+
if (input.startsWith("f/")) {
|
|
262
|
+
for (const folder of folderNames) {
|
|
263
|
+
const folderPath = `f/${folder}/`;
|
|
264
|
+
if (folderPath.startsWith(input) && folderPath !== input) {
|
|
265
|
+
suggestions.push(folderPath);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return suggestions;
|
|
270
|
+
};
|
|
271
|
+
// Ask for path with validation
|
|
272
|
+
let appPath;
|
|
273
|
+
while (true) {
|
|
274
|
+
appPath = await Input.prompt({
|
|
275
|
+
message: "App path (e.g., f/my_folder/my_app or u/username/my_app):",
|
|
276
|
+
minLength: 1,
|
|
277
|
+
suggestions: buildPathSuggestions,
|
|
278
|
+
});
|
|
279
|
+
const validation = validateAppPath(appPath);
|
|
280
|
+
if (validation.valid) {
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
log.error(colors.red(`Invalid path: ${validation.error}`));
|
|
284
|
+
}
|
|
285
|
+
// Ask for framework
|
|
286
|
+
const framework = await Select.prompt({
|
|
287
|
+
message: "Select a framework:",
|
|
288
|
+
options: [
|
|
289
|
+
{ name: "React 19 (Recommended)", value: "react19" },
|
|
290
|
+
{ name: "React 18", value: "react18" },
|
|
291
|
+
{ name: "Svelte 5", value: "svelte5" },
|
|
292
|
+
{ name: "Vue 3", value: "vue" },
|
|
293
|
+
],
|
|
294
|
+
});
|
|
295
|
+
const template = templates[framework];
|
|
296
|
+
if (!template) {
|
|
297
|
+
log.error(colors.red(`Unknown framework: ${framework}`));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
// Data configuration
|
|
301
|
+
let dataConfig = {};
|
|
302
|
+
let createSchemaSQL;
|
|
303
|
+
let schemaName;
|
|
304
|
+
if (datatables.length > 0) {
|
|
305
|
+
log.info("");
|
|
306
|
+
log.info(colors.bold.cyan("Data Configuration"));
|
|
307
|
+
log.info(colors.gray("Configure datatables to enable AI to create and query database tables."));
|
|
308
|
+
// Ask if user wants to configure datatables
|
|
309
|
+
const configureDatatables = await Confirm.prompt({
|
|
310
|
+
message: "Configure datatable for this app?",
|
|
311
|
+
default: true,
|
|
312
|
+
});
|
|
313
|
+
if (configureDatatables) {
|
|
314
|
+
// Select datatable
|
|
315
|
+
const datatableOptions = datatables.map((dt) => ({
|
|
316
|
+
name: dt === "main" ? `${dt} (Recommended)` : dt,
|
|
317
|
+
value: dt,
|
|
318
|
+
}));
|
|
319
|
+
// Put "main" first if it exists
|
|
320
|
+
datatableOptions.sort((a, b) => {
|
|
321
|
+
if (a.value === "main")
|
|
322
|
+
return -1;
|
|
323
|
+
if (b.value === "main")
|
|
324
|
+
return 1;
|
|
325
|
+
return a.value.localeCompare(b.value);
|
|
326
|
+
});
|
|
327
|
+
const selectedDatatable = await Select.prompt({
|
|
328
|
+
message: "Select a datatable:",
|
|
329
|
+
options: datatableOptions,
|
|
330
|
+
});
|
|
331
|
+
dataConfig.datatable = selectedDatatable;
|
|
332
|
+
// Get existing schemas for this datatable
|
|
333
|
+
const existingSchemas = datatableSchemas.get(selectedDatatable) || [];
|
|
334
|
+
// Ask for schema mode
|
|
335
|
+
const schemaOptions = [
|
|
336
|
+
{ name: "Create new schema (Recommended for new apps)", value: "new" },
|
|
337
|
+
];
|
|
338
|
+
if (existingSchemas.length > 0) {
|
|
339
|
+
schemaOptions.push({
|
|
340
|
+
name: "Use existing schema",
|
|
341
|
+
value: "existing",
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
schemaOptions.push({ name: "No schema (use public)", value: "none" });
|
|
345
|
+
const schemaMode = await Select.prompt({
|
|
346
|
+
message: "Schema configuration:",
|
|
347
|
+
options: schemaOptions,
|
|
348
|
+
});
|
|
349
|
+
if (schemaMode === "new") {
|
|
350
|
+
// Generate unique schema name
|
|
351
|
+
const defaultSchemaName = generateUniqueSchemaName(existingSchemas);
|
|
352
|
+
schemaName = await Input.prompt({
|
|
353
|
+
message: "New schema name:",
|
|
354
|
+
default: defaultSchemaName,
|
|
355
|
+
validate: (value) => {
|
|
356
|
+
if (!value.trim()) {
|
|
357
|
+
return "Schema name cannot be empty";
|
|
358
|
+
}
|
|
359
|
+
if (!/^[a-z_][a-z0-9_]*$/.test(value)) {
|
|
360
|
+
return "Schema name must start with a letter or underscore and contain only lowercase letters, numbers, and underscores";
|
|
361
|
+
}
|
|
362
|
+
if (existingSchemas.includes(value)) {
|
|
363
|
+
return `Schema "${value}" already exists`;
|
|
364
|
+
}
|
|
365
|
+
return true;
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
dataConfig.schema = schemaName;
|
|
369
|
+
// Generate SQL to create the schema
|
|
370
|
+
createSchemaSQL = `-- Create schema for ${summary}
|
|
371
|
+
-- This will be executed when you run 'wmill app dev' and confirm in the modal
|
|
372
|
+
CREATE SCHEMA IF NOT EXISTS ${schemaName};
|
|
373
|
+
`;
|
|
374
|
+
}
|
|
375
|
+
else if (schemaMode === "existing") {
|
|
376
|
+
const schemaSelectOptions = existingSchemas.map((s) => ({
|
|
377
|
+
name: s,
|
|
378
|
+
value: s,
|
|
379
|
+
}));
|
|
380
|
+
schemaName = await Select.prompt({
|
|
381
|
+
message: "Select existing schema:",
|
|
382
|
+
options: schemaSelectOptions,
|
|
383
|
+
});
|
|
384
|
+
dataConfig.schema = schemaName;
|
|
385
|
+
}
|
|
386
|
+
// For "none", we don't set a schema
|
|
387
|
+
dataConfig.tables = [];
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
log.info("");
|
|
392
|
+
log.info(colors.yellow("No datatables configured in this workspace. Skipping data configuration."));
|
|
393
|
+
log.info(colors.gray("You can configure datatables in Workspace Settings > Windmill Data Tables"));
|
|
394
|
+
}
|
|
395
|
+
// Create the directory structure - preserve full path (e.g., f/foobar/x/y becomes f/foobar/x/y.raw_app)
|
|
396
|
+
const folderName = `${appPath}.raw_app`;
|
|
397
|
+
const appDir = path.join(dntShim.Deno.cwd(), folderName);
|
|
398
|
+
// Check if directory already exists
|
|
399
|
+
try {
|
|
400
|
+
await dntShim.Deno.stat(appDir);
|
|
401
|
+
const overwrite = await Confirm.prompt({
|
|
402
|
+
message: `Directory '${folderName}' already exists. Overwrite?`,
|
|
403
|
+
default: false,
|
|
404
|
+
});
|
|
405
|
+
if (!overwrite) {
|
|
406
|
+
log.info(colors.yellow("Aborted."));
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
// Directory doesn't exist, which is good
|
|
412
|
+
}
|
|
413
|
+
await ensureDir(appDir);
|
|
414
|
+
await ensureDir(path.join(appDir, "backend"));
|
|
415
|
+
await ensureDir(path.join(appDir, "sql_to_apply"));
|
|
416
|
+
// Create raw_app.yaml with data configuration
|
|
417
|
+
const rawAppConfig = {
|
|
418
|
+
summary,
|
|
419
|
+
};
|
|
420
|
+
// Add data configuration if present
|
|
421
|
+
if (dataConfig.datatable) {
|
|
422
|
+
rawAppConfig.data = dataConfig;
|
|
423
|
+
}
|
|
424
|
+
await dntShim.Deno.writeTextFile(path.join(appDir, "raw_app.yaml"), yamlStringify(rawAppConfig, yamlOptions));
|
|
425
|
+
// Create template files
|
|
426
|
+
for (const [filePath, content] of Object.entries(template.files)) {
|
|
427
|
+
const fullPath = path.join(appDir, filePath.slice(1)); // Remove leading slash
|
|
428
|
+
await dntShim.Deno.writeTextFile(fullPath, content.trim() + "\n");
|
|
429
|
+
}
|
|
430
|
+
// Create AGENTS.md - main documentation for AI agents
|
|
431
|
+
const dataForDocs = dataConfig.datatable
|
|
432
|
+
? {
|
|
433
|
+
tables: dataConfig.tables,
|
|
434
|
+
datatable: dataConfig.datatable,
|
|
435
|
+
schema: dataConfig.schema,
|
|
436
|
+
}
|
|
437
|
+
: undefined;
|
|
438
|
+
const agentsContent = generateAgentsDocumentation(dataForDocs);
|
|
439
|
+
await dntShim.Deno.writeTextFile(path.join(appDir, "AGENTS.md"), agentsContent);
|
|
440
|
+
// Create DATATABLES.md with the configured data
|
|
441
|
+
const datatablesContent = generateDatatablesDocumentation(dataForDocs);
|
|
442
|
+
await dntShim.Deno.writeTextFile(path.join(appDir, "DATATABLES.md"), datatablesContent);
|
|
443
|
+
// Create example backend runnable
|
|
444
|
+
const exampleRunnable = {
|
|
445
|
+
type: "inline",
|
|
446
|
+
path: undefined,
|
|
447
|
+
};
|
|
448
|
+
await dntShim.Deno.writeTextFile(path.join(appDir, "backend", "a.yaml"), yamlStringify(exampleRunnable, yamlOptions));
|
|
449
|
+
await dntShim.Deno.writeTextFile(path.join(appDir, "backend", "a.ts"), `export async function main(x: number): Promise<string> {
|
|
450
|
+
return \`Hello from backend! x = \${x}\`;
|
|
451
|
+
}
|
|
452
|
+
`);
|
|
453
|
+
// Create sql_to_apply README
|
|
454
|
+
await dntShim.Deno.writeTextFile(path.join(appDir, "sql_to_apply", "README.md"), `# SQL Migrations Folder
|
|
455
|
+
|
|
456
|
+
This folder is for SQL migration files that will be applied to datatables during development.
|
|
457
|
+
|
|
458
|
+
## How to Use
|
|
459
|
+
|
|
460
|
+
1. Configure a datatable in \`raw_app.yaml\`:
|
|
461
|
+
\`\`\`yaml
|
|
462
|
+
data:
|
|
463
|
+
datatable: main # Your datatable name
|
|
464
|
+
tables: [] # Add tables here after creating them
|
|
465
|
+
\`\`\`
|
|
466
|
+
|
|
467
|
+
2. Create SQL files in this folder (e.g., \`001_create_users.sql\`)
|
|
468
|
+
|
|
469
|
+
3. Run \`wmill app dev .\` - the dev server watches this folder
|
|
470
|
+
|
|
471
|
+
4. When a SQL file is created/modified, a modal appears to confirm execution
|
|
472
|
+
|
|
473
|
+
5. After creating tables, add them to \`data.tables\` in \`raw_app.yaml\`
|
|
474
|
+
|
|
475
|
+
## Important
|
|
476
|
+
|
|
477
|
+
- This folder is **excluded from push** - SQL files are not synced
|
|
478
|
+
- Always add created tables to \`data.tables\` so your app can access them
|
|
479
|
+
- Use idempotent SQL (\`CREATE TABLE IF NOT EXISTS\`, etc.)
|
|
480
|
+
`);
|
|
481
|
+
// Create schema creation SQL file if a new schema was requested
|
|
482
|
+
if (createSchemaSQL && schemaName) {
|
|
483
|
+
await dntShim.Deno.writeTextFile(path.join(appDir, "sql_to_apply", `000_create_schema_${schemaName}.sql`), createSchemaSQL);
|
|
484
|
+
}
|
|
485
|
+
log.info("");
|
|
486
|
+
log.info(colors.bold.green(`App created successfully at ${folderName}/`));
|
|
487
|
+
log.info("");
|
|
488
|
+
log.info(colors.gray("Directory structure:"));
|
|
489
|
+
log.info(colors.gray(` ${folderName}/`));
|
|
490
|
+
log.info(colors.gray(" ├── AGENTS.md ← Read this first!"));
|
|
491
|
+
log.info(colors.gray(" ├── raw_app.yaml"));
|
|
492
|
+
log.info(colors.gray(" ├── DATATABLES.md"));
|
|
493
|
+
for (const filePath of Object.keys(template.files)) {
|
|
494
|
+
log.info(colors.gray(` ├── ${filePath.slice(1)}`));
|
|
495
|
+
}
|
|
496
|
+
log.info(colors.gray(" ├── backend/"));
|
|
497
|
+
log.info(colors.gray(" │ ├── a.yaml"));
|
|
498
|
+
log.info(colors.gray(" │ └── a.ts"));
|
|
499
|
+
log.info(colors.gray(" └── sql_to_apply/"));
|
|
500
|
+
log.info(colors.gray(" ├── README.md"));
|
|
501
|
+
if (createSchemaSQL && schemaName) {
|
|
502
|
+
log.info(colors.gray(` └── 000_create_schema_${schemaName}.sql`));
|
|
503
|
+
}
|
|
504
|
+
log.info("");
|
|
505
|
+
// Show data configuration summary
|
|
506
|
+
if (dataConfig.datatable) {
|
|
507
|
+
log.info(colors.cyan("Data configuration:"));
|
|
508
|
+
log.info(colors.gray(` Datatable: ${dataConfig.datatable}`));
|
|
509
|
+
if (dataConfig.schema) {
|
|
510
|
+
log.info(colors.gray(` Schema: ${dataConfig.schema}`));
|
|
511
|
+
}
|
|
512
|
+
log.info("");
|
|
513
|
+
}
|
|
514
|
+
// Advise to run wmill app dev
|
|
515
|
+
log.info(colors.bold.cyan("Next steps:"));
|
|
516
|
+
log.info(colors.gray(` 1. cd ${folderName}`));
|
|
517
|
+
log.info(colors.gray(" 2. npm install"));
|
|
518
|
+
log.info(colors.bold.white(" 3. wmill app dev .") +
|
|
519
|
+
colors.gray(" (start dev server)"));
|
|
520
|
+
if (createSchemaSQL) {
|
|
521
|
+
log.info("");
|
|
522
|
+
log.info(colors.yellow(` A SQL file to create schema '${schemaName}' has been added to sql_to_apply/`));
|
|
523
|
+
log.info(colors.yellow(" The dev server will prompt you to apply it when you start."));
|
|
524
|
+
}
|
|
525
|
+
log.info("");
|
|
526
|
+
log.info(colors.gray(" 4. wmill sync push (to deploy when ready)"));
|
|
527
|
+
}
|
|
528
|
+
// deno-lint-ignore no-explicit-any
|
|
529
|
+
const command = new Command()
|
|
530
|
+
.description("create a new raw app from a template")
|
|
531
|
+
.action(newApp);
|
|
532
|
+
export default command;
|
|
@@ -44,8 +44,33 @@ async function findRunnableContentFile(backendPath, runnableId, allFiles) {
|
|
|
44
44
|
return undefined;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
47
|
+
* Extracts the runnable ID from a code file name.
|
|
48
|
+
* Returns undefined if the file is not a recognized code file.
|
|
49
|
+
*
|
|
50
|
+
* Examples:
|
|
51
|
+
* - "get_user.ts" -> "get_user"
|
|
52
|
+
* - "fetch_data.bun.ts" -> "fetch_data"
|
|
53
|
+
* - "query.pg.sql" -> "query"
|
|
54
|
+
*/
|
|
55
|
+
function getRunnableIdFromCodeFile(fileName) {
|
|
56
|
+
// Skip yaml and lock files
|
|
57
|
+
if (fileName.endsWith(".yaml") || fileName.endsWith(".lock")) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
// Try to find a matching extension
|
|
61
|
+
for (const ext of Object.keys(EXTENSION_TO_LANGUAGE)) {
|
|
62
|
+
if (fileName.endsWith("." + ext)) {
|
|
63
|
+
return fileName.slice(0, -(ext.length + 1));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Loads all runnables from the backend folder.
|
|
70
|
+
*
|
|
71
|
+
* Supports two modes:
|
|
72
|
+
* 1. Explicit YAML config: `<id>.yaml` with type specification + optional `<id>.<ext>` code file
|
|
73
|
+
* 2. Code-only (auto-detect): Just `<id>.<ext>` - assumes type: inline with empty fields
|
|
49
74
|
*
|
|
50
75
|
* Converts from file format to API format:
|
|
51
76
|
* - For inline scripts (type: 'inline'): derives inlineScript from sibling files
|
|
@@ -67,12 +92,15 @@ export async function loadRunnablesFromBackend(backendPath, defaultTs = "bun") {
|
|
|
67
92
|
allFiles.push(entry.name);
|
|
68
93
|
}
|
|
69
94
|
}
|
|
70
|
-
//
|
|
95
|
+
// Track which runnable IDs have been processed (from YAML files)
|
|
96
|
+
const processedIds = new Set();
|
|
97
|
+
// Process YAML files first (explicit configuration)
|
|
71
98
|
for (const fileName of allFiles) {
|
|
72
99
|
if (!fileName.endsWith(".yaml")) {
|
|
73
100
|
continue;
|
|
74
101
|
}
|
|
75
102
|
const runnableId = fileName.replace(".yaml", "");
|
|
103
|
+
processedIds.add(runnableId);
|
|
76
104
|
const filePath = path.join(backendPath, fileName);
|
|
77
105
|
const runnable = (await yamlParseFile(filePath));
|
|
78
106
|
// If this is an inline script (type: 'inline'), derive inlineScript from files
|
|
@@ -112,6 +140,39 @@ export async function loadRunnablesFromBackend(backendPath, defaultTs = "bun") {
|
|
|
112
140
|
}
|
|
113
141
|
runnables[runnableId] = runnable;
|
|
114
142
|
}
|
|
143
|
+
// Auto-detect code files without YAML config (assume type: inline)
|
|
144
|
+
for (const fileName of allFiles) {
|
|
145
|
+
const runnableId = getRunnableIdFromCodeFile(fileName);
|
|
146
|
+
if (!runnableId) {
|
|
147
|
+
continue; // Not a recognized code file
|
|
148
|
+
}
|
|
149
|
+
if (processedIds.has(runnableId)) {
|
|
150
|
+
continue; // Already processed via YAML file
|
|
151
|
+
}
|
|
152
|
+
// Found a code file without corresponding YAML - treat as inline runnable
|
|
153
|
+
processedIds.add(runnableId);
|
|
154
|
+
const contentFile = await findRunnableContentFile(backendPath, runnableId, allFiles);
|
|
155
|
+
if (contentFile) {
|
|
156
|
+
const language = getLanguageFromExtension(contentFile.ext, defaultTs);
|
|
157
|
+
// Try to load lock file
|
|
158
|
+
let lock;
|
|
159
|
+
try {
|
|
160
|
+
lock = await dntShim.Deno.readTextFile(path.join(backendPath, `${runnableId}.lock`));
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// No lock file, that's fine
|
|
164
|
+
}
|
|
165
|
+
// Create inline runnable with default empty fields
|
|
166
|
+
runnables[runnableId] = {
|
|
167
|
+
type: "inline",
|
|
168
|
+
inlineScript: {
|
|
169
|
+
content: contentFile.content,
|
|
170
|
+
language,
|
|
171
|
+
...(lock ? { lock } : {}),
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
115
176
|
}
|
|
116
177
|
catch (error) {
|
|
117
178
|
if (error.name !== "NotFound") {
|
|
@@ -151,20 +212,23 @@ async function collectAppFiles(localPath) {
|
|
|
151
212
|
const fullPath = dir + entry.name;
|
|
152
213
|
const relativePath = basePath + entry.name;
|
|
153
214
|
if (entry.isDirectory) {
|
|
154
|
-
// Skip the runnables and
|
|
215
|
+
// Skip the runnables, node_modules, and sql_to_apply subfolders
|
|
155
216
|
if (entry.name === APP_BACKEND_FOLDER ||
|
|
156
217
|
entry.name === "node_modules" ||
|
|
157
218
|
entry.name === "dist" ||
|
|
158
|
-
entry.name === ".claude"
|
|
219
|
+
entry.name === ".claude" ||
|
|
220
|
+
entry.name === "sql_to_apply") {
|
|
159
221
|
continue;
|
|
160
222
|
}
|
|
161
223
|
await readDirRecursive(fullPath + SEP, relativePath + SEP);
|
|
162
224
|
}
|
|
163
225
|
else if (entry.isFile) {
|
|
164
|
-
// Skip
|
|
165
|
-
// Skip package-lock.json as it's generated
|
|
226
|
+
// Skip generated/metadata files that shouldn't be part of the app
|
|
166
227
|
if (entry.name === "raw_app.yaml" ||
|
|
167
|
-
entry.name === "package-lock.json"
|
|
228
|
+
entry.name === "package-lock.json" ||
|
|
229
|
+
entry.name === "DATATABLES.md" ||
|
|
230
|
+
entry.name === "AGENTS.md" ||
|
|
231
|
+
entry.name === "wmill.d.ts") {
|
|
168
232
|
continue;
|
|
169
233
|
}
|
|
170
234
|
const content = await dntShim.Deno.readTextFile(fullPath);
|
|
@@ -262,7 +326,7 @@ export async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
262
326
|
summary: localApp.summary,
|
|
263
327
|
policy: appForPolicy.policy,
|
|
264
328
|
deployment_message: message,
|
|
265
|
-
custom_path: localApp.custom_path,
|
|
329
|
+
...(localApp.custom_path ? { custom_path: localApp.custom_path } : {}),
|
|
266
330
|
},
|
|
267
331
|
js,
|
|
268
332
|
css,
|
|
@@ -280,7 +344,7 @@ export async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
280
344
|
summary: localApp.summary,
|
|
281
345
|
policy: appForPolicy.policy,
|
|
282
346
|
deployment_message: message,
|
|
283
|
-
custom_path: localApp.custom_path,
|
|
347
|
+
...(localApp.custom_path ? { custom_path: localApp.custom_path } : {}),
|
|
284
348
|
},
|
|
285
349
|
js,
|
|
286
350
|
css,
|