@dashai/cli 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +297 -45
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -2032,6 +2032,47 @@ var init_init = __esm({
|
|
|
2032
2032
|
init_workspaces();
|
|
2033
2033
|
}
|
|
2034
2034
|
});
|
|
2035
|
+
function loadSchemaCommandContext(opts) {
|
|
2036
|
+
const projectRoot = resolve(opts.dir ?? process.cwd());
|
|
2037
|
+
const manifestPath2 = join(projectRoot, "module.json");
|
|
2038
|
+
const manifest = readManifestOrThrow(projectRoot);
|
|
2039
|
+
const manifestRawBytes = readFileSync(manifestPath2, "utf-8");
|
|
2040
|
+
const slug = manifest.module?.slug;
|
|
2041
|
+
if (!slug) {
|
|
2042
|
+
throw new Error(
|
|
2043
|
+
`module.json at ${manifestPath2} has no module.slug \u2014 the manifest is malformed.`
|
|
2044
|
+
);
|
|
2045
|
+
}
|
|
2046
|
+
const cfg = readConfig();
|
|
2047
|
+
if (!cfg) {
|
|
2048
|
+
throw new Error("Not logged in. Run `dashwise login` first.");
|
|
2049
|
+
}
|
|
2050
|
+
const entry = readModuleEntry(slug);
|
|
2051
|
+
if (!entry) {
|
|
2052
|
+
throw new Error(
|
|
2053
|
+
`No dev install cached for module "${slug}". Run \`dashwise init ${slug} --force\` to provision one.`
|
|
2054
|
+
);
|
|
2055
|
+
}
|
|
2056
|
+
return {
|
|
2057
|
+
projectRoot,
|
|
2058
|
+
manifestPath: manifestPath2,
|
|
2059
|
+
manifest,
|
|
2060
|
+
manifestRawBytes,
|
|
2061
|
+
slug,
|
|
2062
|
+
cfg,
|
|
2063
|
+
entry,
|
|
2064
|
+
requestOptions: {
|
|
2065
|
+
baseUrl: resolveApiUrl(),
|
|
2066
|
+
auth: { token: entry.runtimeToken }
|
|
2067
|
+
}
|
|
2068
|
+
};
|
|
2069
|
+
}
|
|
2070
|
+
var init_schema_command_context = __esm({
|
|
2071
|
+
"src/lib/schema-command-context.ts"() {
|
|
2072
|
+
init_config();
|
|
2073
|
+
init_manifest_io();
|
|
2074
|
+
}
|
|
2075
|
+
});
|
|
2035
2076
|
|
|
2036
2077
|
// src/commands/module/destroy-dev-install.ts
|
|
2037
2078
|
var destroy_dev_install_exports = {};
|
|
@@ -2202,47 +2243,6 @@ var init_reset_dev_install = __esm({
|
|
|
2202
2243
|
init_output();
|
|
2203
2244
|
}
|
|
2204
2245
|
});
|
|
2205
|
-
function loadSchemaCommandContext(opts) {
|
|
2206
|
-
const projectRoot = resolve(opts.dir ?? process.cwd());
|
|
2207
|
-
const manifestPath2 = join(projectRoot, "module.json");
|
|
2208
|
-
const manifest = readManifestOrThrow(projectRoot);
|
|
2209
|
-
const manifestRawBytes = readFileSync(manifestPath2, "utf-8");
|
|
2210
|
-
const slug = manifest.module?.slug;
|
|
2211
|
-
if (!slug) {
|
|
2212
|
-
throw new Error(
|
|
2213
|
-
`module.json at ${manifestPath2} has no module.slug \u2014 the manifest is malformed.`
|
|
2214
|
-
);
|
|
2215
|
-
}
|
|
2216
|
-
const cfg = readConfig();
|
|
2217
|
-
if (!cfg) {
|
|
2218
|
-
throw new Error("Not logged in. Run `dashwise login` first.");
|
|
2219
|
-
}
|
|
2220
|
-
const entry = readModuleEntry(slug);
|
|
2221
|
-
if (!entry) {
|
|
2222
|
-
throw new Error(
|
|
2223
|
-
`No dev install cached for module "${slug}". Run \`dashwise init ${slug} --force\` to provision one.`
|
|
2224
|
-
);
|
|
2225
|
-
}
|
|
2226
|
-
return {
|
|
2227
|
-
projectRoot,
|
|
2228
|
-
manifestPath: manifestPath2,
|
|
2229
|
-
manifest,
|
|
2230
|
-
manifestRawBytes,
|
|
2231
|
-
slug,
|
|
2232
|
-
cfg,
|
|
2233
|
-
entry,
|
|
2234
|
-
requestOptions: {
|
|
2235
|
-
baseUrl: resolveApiUrl(),
|
|
2236
|
-
auth: { token: entry.runtimeToken }
|
|
2237
|
-
}
|
|
2238
|
-
};
|
|
2239
|
-
}
|
|
2240
|
-
var init_schema_command_context = __esm({
|
|
2241
|
-
"src/lib/schema-command-context.ts"() {
|
|
2242
|
-
init_config();
|
|
2243
|
-
init_manifest_io();
|
|
2244
|
-
}
|
|
2245
|
-
});
|
|
2246
2246
|
|
|
2247
2247
|
// src/lib/field-spec.ts
|
|
2248
2248
|
function parseFieldSpec(spec) {
|
|
@@ -2707,10 +2707,76 @@ var init_set_type = __esm({
|
|
|
2707
2707
|
init_api_client();
|
|
2708
2708
|
init_config();
|
|
2709
2709
|
init_manifest_io();
|
|
2710
|
+
|
|
2711
|
+
// src/lib/manifest-poll.ts
|
|
2712
|
+
init_api_client();
|
|
2713
|
+
function startManifestPollLoop(opts) {
|
|
2714
|
+
const {
|
|
2715
|
+
installationId,
|
|
2716
|
+
manifestPath: manifestPath2,
|
|
2717
|
+
requestOptions,
|
|
2718
|
+
intervalMs,
|
|
2719
|
+
onUpdate,
|
|
2720
|
+
onError
|
|
2721
|
+
} = opts;
|
|
2722
|
+
let lastSeenJson = existsSync(manifestPath2) ? readFileSync(manifestPath2, "utf-8") : "";
|
|
2723
|
+
let timer = null;
|
|
2724
|
+
let stopped = false;
|
|
2725
|
+
const tick = async () => {
|
|
2726
|
+
if (stopped) return;
|
|
2727
|
+
try {
|
|
2728
|
+
const { manifest } = await getInstallationSchema(
|
|
2729
|
+
installationId,
|
|
2730
|
+
requestOptions
|
|
2731
|
+
);
|
|
2732
|
+
const remoteJson = JSON.stringify(manifest, null, 2) + "\n";
|
|
2733
|
+
const currentLocal = existsSync(manifestPath2) ? readFileSync(manifestPath2, "utf-8") : "";
|
|
2734
|
+
if (remoteJson === currentLocal) {
|
|
2735
|
+
lastSeenJson = remoteJson;
|
|
2736
|
+
} else if (remoteJson !== lastSeenJson) {
|
|
2737
|
+
writeFileSync(manifestPath2, remoteJson, "utf-8");
|
|
2738
|
+
lastSeenJson = remoteJson;
|
|
2739
|
+
if (onUpdate) {
|
|
2740
|
+
const delta = Buffer.byteLength(remoteJson, "utf8") - Buffer.byteLength(currentLocal, "utf8");
|
|
2741
|
+
const deltaStr = delta === 0 ? "0 bytes" : `${delta > 0 ? "+" : ""}${delta} bytes`;
|
|
2742
|
+
onUpdate(
|
|
2743
|
+
`Backend manifest changed \u2014 synced to module.json (${deltaStr}).`
|
|
2744
|
+
);
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
} catch (err) {
|
|
2748
|
+
if (onError) {
|
|
2749
|
+
const message = err instanceof ApiError ? `${err.code} (HTTP ${err.status}): ${err.message}` : err.message;
|
|
2750
|
+
onError(new Error(message));
|
|
2751
|
+
}
|
|
2752
|
+
} finally {
|
|
2753
|
+
if (!stopped) {
|
|
2754
|
+
timer = setTimeout(() => void tick(), intervalMs);
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
};
|
|
2758
|
+
timer = setTimeout(() => void tick(), intervalMs);
|
|
2759
|
+
return {
|
|
2760
|
+
stop: () => {
|
|
2761
|
+
if (stopped) return;
|
|
2762
|
+
stopped = true;
|
|
2763
|
+
if (timer) {
|
|
2764
|
+
clearTimeout(timer);
|
|
2765
|
+
timer = null;
|
|
2766
|
+
}
|
|
2767
|
+
},
|
|
2768
|
+
isRunning: () => !stopped
|
|
2769
|
+
};
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2772
|
+
// src/commands/dev.ts
|
|
2710
2773
|
init_output();
|
|
2711
2774
|
var DEFAULT_NEXT_PORT = 3e3;
|
|
2712
2775
|
var PREFIX_SDK = `\x1B[36m[sdk]\x1B[0m `;
|
|
2713
2776
|
var PREFIX_NEXT = `\x1B[35m[next]\x1B[0m `;
|
|
2777
|
+
var PREFIX_POLL = `\x1B[33m[poll]\x1B[0m `;
|
|
2778
|
+
var DEFAULT_REMOTE_POLL_INTERVAL_SEC = 5;
|
|
2779
|
+
var MIN_REMOTE_POLL_INTERVAL_SEC = 1;
|
|
2714
2780
|
async function devCommand(options) {
|
|
2715
2781
|
if (options.sdkOnly && options.nextOnly) {
|
|
2716
2782
|
fail(
|
|
@@ -2748,7 +2814,13 @@ async function devCommand(options) {
|
|
|
2748
2814
|
return 1;
|
|
2749
2815
|
}
|
|
2750
2816
|
const apiUrl = options.apiUrl ?? process.env.DASHWISE_API_URL ?? savedConfig?.apiUrl ?? "http://localhost:3000";
|
|
2751
|
-
|
|
2817
|
+
let port;
|
|
2818
|
+
try {
|
|
2819
|
+
port = await resolveDevPort(options.port);
|
|
2820
|
+
} catch (err) {
|
|
2821
|
+
fail(err.message);
|
|
2822
|
+
return 1;
|
|
2823
|
+
}
|
|
2752
2824
|
const explicitInstallationId = options.installationId ?? process.env.DASHWISE_INSTALLATION_ID;
|
|
2753
2825
|
const reuseDevSessionId = process.env.DASHWISE_DEV_SESSION_ID;
|
|
2754
2826
|
const moduleEntry = manifestSlug !== void 0 ? readModuleEntry(manifestSlug) : null;
|
|
@@ -2839,10 +2911,43 @@ async function devCommand(options) {
|
|
|
2839
2911
|
pipeWithPrefix(child.stdout, process.stdout, prefix);
|
|
2840
2912
|
pipeWithPrefix(child.stderr, process.stderr, prefix);
|
|
2841
2913
|
}
|
|
2914
|
+
let manifestPoll = null;
|
|
2915
|
+
const enablePoll = !options.noRemotePoll && moduleEntry !== void 0 && manifestSlug !== void 0;
|
|
2916
|
+
if (enablePoll) {
|
|
2917
|
+
const intervalSec = Math.max(
|
|
2918
|
+
MIN_REMOTE_POLL_INTERVAL_SEC,
|
|
2919
|
+
options.remotePollIntervalSec ?? DEFAULT_REMOTE_POLL_INTERVAL_SEC
|
|
2920
|
+
);
|
|
2921
|
+
manifestPoll = startManifestPollLoop({
|
|
2922
|
+
installationId: moduleEntry.installationId,
|
|
2923
|
+
manifestPath: manifestPath2,
|
|
2924
|
+
requestOptions: {
|
|
2925
|
+
baseUrl: apiUrl,
|
|
2926
|
+
auth: { token: moduleEntry.runtimeToken }
|
|
2927
|
+
},
|
|
2928
|
+
intervalMs: intervalSec * 1e3,
|
|
2929
|
+
onUpdate: (msg) => {
|
|
2930
|
+
process.stdout.write(`${PREFIX_POLL}${msg}
|
|
2931
|
+
`);
|
|
2932
|
+
},
|
|
2933
|
+
onError: (err) => {
|
|
2934
|
+
process.stderr.write(`${PREFIX_POLL}${err.message}
|
|
2935
|
+
`);
|
|
2936
|
+
}
|
|
2937
|
+
});
|
|
2938
|
+
info(
|
|
2939
|
+
` ${dim("poll")} backend manifest every ${intervalSec}s ${dim("(--no-remote-poll to disable)")}`
|
|
2940
|
+
);
|
|
2941
|
+
info("");
|
|
2942
|
+
}
|
|
2842
2943
|
let shuttingDown = false;
|
|
2843
2944
|
const forwardSignal = (sig) => {
|
|
2844
2945
|
if (shuttingDown) return;
|
|
2845
2946
|
shuttingDown = true;
|
|
2947
|
+
if (manifestPoll) {
|
|
2948
|
+
manifestPoll.stop();
|
|
2949
|
+
manifestPoll = null;
|
|
2950
|
+
}
|
|
2846
2951
|
info(`
|
|
2847
2952
|
Received ${sig}, stopping children\u2026`);
|
|
2848
2953
|
for (const { child } of children) {
|
|
@@ -2879,6 +2984,10 @@ Received ${sig}, stopping children\u2026`);
|
|
|
2879
2984
|
}
|
|
2880
2985
|
}
|
|
2881
2986
|
}
|
|
2987
|
+
if (manifestPoll) {
|
|
2988
|
+
manifestPoll.stop();
|
|
2989
|
+
manifestPoll = null;
|
|
2990
|
+
}
|
|
2882
2991
|
const exitCode = Math.max(0, ...results.map((r) => r.code));
|
|
2883
2992
|
if (exitCode === 0) {
|
|
2884
2993
|
success("Dev loop stopped cleanly.");
|
|
@@ -2951,6 +3060,44 @@ function computeCallbackOrigins(port, extra) {
|
|
|
2951
3060
|
const def = `http://localhost:${port}`;
|
|
2952
3061
|
return Array.from(/* @__PURE__ */ new Set([def, ...extra]));
|
|
2953
3062
|
}
|
|
3063
|
+
var PORT_PROBE_LIMIT = 10;
|
|
3064
|
+
async function resolveDevPort(requested) {
|
|
3065
|
+
if (requested !== void 0) {
|
|
3066
|
+
if (await isPortFree(requested)) return requested;
|
|
3067
|
+
const suggestion = await findFirstFreePort(requested + 1, PORT_PROBE_LIMIT);
|
|
3068
|
+
const suggestionHint = suggestion !== null ? `Try \`dashwise dev --port ${suggestion}\`.` : `No free port found between ${requested + 1} and ${requested + PORT_PROBE_LIMIT} either \u2014 check what's listening with \`lsof -i :${requested}\`.`;
|
|
3069
|
+
throw new Error(
|
|
3070
|
+
`Port ${requested} is already in use. ${suggestionHint}`
|
|
3071
|
+
);
|
|
3072
|
+
}
|
|
3073
|
+
const found = await findFirstFreePort(DEFAULT_NEXT_PORT, PORT_PROBE_LIMIT);
|
|
3074
|
+
if (found === null) {
|
|
3075
|
+
throw new Error(
|
|
3076
|
+
`No free port found between ${DEFAULT_NEXT_PORT} and ${DEFAULT_NEXT_PORT + PORT_PROBE_LIMIT - 1}. Free a port (e.g. \`lsof -i :${DEFAULT_NEXT_PORT}\`) or pass \`--port <N>\` explicitly.`
|
|
3077
|
+
);
|
|
3078
|
+
}
|
|
3079
|
+
return found;
|
|
3080
|
+
}
|
|
3081
|
+
async function isPortFree(port) {
|
|
3082
|
+
const { createServer } = await import('net');
|
|
3083
|
+
return new Promise((resolve11) => {
|
|
3084
|
+
const server = createServer();
|
|
3085
|
+
server.once("error", () => {
|
|
3086
|
+
resolve11(false);
|
|
3087
|
+
});
|
|
3088
|
+
server.once("listening", () => {
|
|
3089
|
+
server.close(() => resolve11(true));
|
|
3090
|
+
});
|
|
3091
|
+
server.listen(port, "0.0.0.0");
|
|
3092
|
+
});
|
|
3093
|
+
}
|
|
3094
|
+
async function findFirstFreePort(start, limit) {
|
|
3095
|
+
for (let i = 0; i < limit; i++) {
|
|
3096
|
+
const port = start + i;
|
|
3097
|
+
if (await isPortFree(port)) return port;
|
|
3098
|
+
}
|
|
3099
|
+
return null;
|
|
3100
|
+
}
|
|
2954
3101
|
async function resolveTargetWorkspace(apiUrl, apiToken, flag) {
|
|
2955
3102
|
const workspaces = await apiRequest(
|
|
2956
3103
|
"GET",
|
|
@@ -4986,6 +5133,92 @@ async function depsRemoveCommand(providerSlug, options) {
|
|
|
4986
5133
|
return 0;
|
|
4987
5134
|
}
|
|
4988
5135
|
|
|
5136
|
+
// src/commands/pull.ts
|
|
5137
|
+
init_api_client();
|
|
5138
|
+
init_manifest_io();
|
|
5139
|
+
init_schema_command_context();
|
|
5140
|
+
init_output();
|
|
5141
|
+
async function pullCommand(options) {
|
|
5142
|
+
let ctx;
|
|
5143
|
+
try {
|
|
5144
|
+
ctx = loadSchemaCommandContext({
|
|
5145
|
+
...options.dir !== void 0 ? { dir: options.dir } : {}
|
|
5146
|
+
});
|
|
5147
|
+
} catch (err) {
|
|
5148
|
+
fail(err.message);
|
|
5149
|
+
return 1;
|
|
5150
|
+
}
|
|
5151
|
+
info(`Pulling manifest for installation ${ctx.entry.installationId}\u2026`);
|
|
5152
|
+
let remoteManifest;
|
|
5153
|
+
try {
|
|
5154
|
+
const response = await getInstallationSchema(
|
|
5155
|
+
ctx.entry.installationId,
|
|
5156
|
+
ctx.requestOptions
|
|
5157
|
+
);
|
|
5158
|
+
remoteManifest = response.manifest;
|
|
5159
|
+
} catch (err) {
|
|
5160
|
+
return surfacePullFailure(err);
|
|
5161
|
+
}
|
|
5162
|
+
const localJson = JSON.stringify(ctx.manifest, null, 2) + "\n";
|
|
5163
|
+
const remoteJson = JSON.stringify(remoteManifest, null, 2) + "\n";
|
|
5164
|
+
if (localJson === remoteJson) {
|
|
5165
|
+
success("Already in sync \u2014 local module.json matches backend.");
|
|
5166
|
+
return 0;
|
|
5167
|
+
}
|
|
5168
|
+
const localBytes = Buffer.byteLength(localJson, "utf8");
|
|
5169
|
+
const remoteBytes = Buffer.byteLength(remoteJson, "utf8");
|
|
5170
|
+
const delta = remoteBytes - localBytes;
|
|
5171
|
+
const deltaStr = delta === 0 ? "0 bytes" : `${delta > 0 ? "+" : ""}${delta} bytes`;
|
|
5172
|
+
if (options.dryRun) {
|
|
5173
|
+
info(
|
|
5174
|
+
`Drift detected (${deltaStr}). ${code("--dry-run")} \u2014 not writing.`
|
|
5175
|
+
);
|
|
5176
|
+
info(`Run ${code("dashwise pull")} without ${code("--dry-run")} to apply.`);
|
|
5177
|
+
return 0;
|
|
5178
|
+
}
|
|
5179
|
+
try {
|
|
5180
|
+
writeManifest(remoteManifest, ctx.projectRoot);
|
|
5181
|
+
} catch (err) {
|
|
5182
|
+
fail(`Failed to write ${manifestPath(ctx.projectRoot)}: ${err.message}`);
|
|
5183
|
+
return 1;
|
|
5184
|
+
}
|
|
5185
|
+
success(
|
|
5186
|
+
`Synced module.json from backend (${deltaStr}). ${dim(`Run \`dashwise module generate\` to refresh typed SDK if your watcher isn't running.`)}`
|
|
5187
|
+
);
|
|
5188
|
+
return 0;
|
|
5189
|
+
}
|
|
5190
|
+
function surfacePullFailure(err) {
|
|
5191
|
+
if (err instanceof ApiError) {
|
|
5192
|
+
switch (err.code) {
|
|
5193
|
+
case "UNAUTHENTICATED":
|
|
5194
|
+
fail(
|
|
5195
|
+
`Runtime token rejected. The cached token for this module may be expired \u2014 re-run \`dashwise init <slug> --force\` to mint a fresh one.`
|
|
5196
|
+
);
|
|
5197
|
+
break;
|
|
5198
|
+
case "SANDBOX_TOKEN_NOT_ACCEPTED":
|
|
5199
|
+
fail(
|
|
5200
|
+
`Schema-read endpoint requires a local-dev runtime token (kind=local). The cached token is the wrong kind \u2014 re-run \`dashwise init <slug> --force\`.`
|
|
5201
|
+
);
|
|
5202
|
+
break;
|
|
5203
|
+
case "INSTALL_MISMATCH":
|
|
5204
|
+
fail(
|
|
5205
|
+
`Runtime token is bound to a different installation than expected. The cached install id may be stale \u2014 re-run \`dashwise init <slug> --force\`.`
|
|
5206
|
+
);
|
|
5207
|
+
break;
|
|
5208
|
+
case "INSTALLATION_NOT_FOUND":
|
|
5209
|
+
fail(
|
|
5210
|
+
`The backend has no record of this installation. It may have been destroyed (GC, manual cleanup). Re-run \`dashwise init <slug>\` to provision a fresh one.`
|
|
5211
|
+
);
|
|
5212
|
+
break;
|
|
5213
|
+
default:
|
|
5214
|
+
fail(`Backend rejected: ${err.code} ${err.status} \u2014 ${err.message}`);
|
|
5215
|
+
}
|
|
5216
|
+
return 1;
|
|
5217
|
+
}
|
|
5218
|
+
fail(`Pull failed: ${err.message}`);
|
|
5219
|
+
return 1;
|
|
5220
|
+
}
|
|
5221
|
+
|
|
4989
5222
|
// src/commands/query.ts
|
|
4990
5223
|
init_manifest_io();
|
|
4991
5224
|
init_output();
|
|
@@ -5591,7 +5824,14 @@ program.command("dev").description(
|
|
|
5591
5824
|
).option(
|
|
5592
5825
|
"--api-url <url>",
|
|
5593
5826
|
"Override the `DASHWISE_API_URL` env var passed to children (default: saved CLI config)."
|
|
5594
|
-
).option("--port <number>", "Port for `next dev` (default: 3000).", parseIntOption).option("--sdk-only", "Only run the manifest watcher; skip `next dev`.").option("--next-only", "Only run `next dev`; skip the manifest watcher.").
|
|
5827
|
+
).option("--port <number>", "Port for `next dev` (default: 3000).", parseIntOption).option("--sdk-only", "Only run the manifest watcher; skip `next dev`.").option("--next-only", "Only run `next dev`; skip the manifest watcher.").option(
|
|
5828
|
+
"--no-remote-poll",
|
|
5829
|
+
"Disable periodic backend manifest polling. By default, `dashwise dev` polls `GET /api/installations/:id/schema` every few seconds + writes module.json when the backend has advanced (dashboard edits, AI builder mutations, teammate commands)."
|
|
5830
|
+
).option(
|
|
5831
|
+
"--remote-poll-interval <seconds>",
|
|
5832
|
+
"Backend manifest poll interval, in seconds. Default: 5. Minimum: 1.",
|
|
5833
|
+
parseIntOption
|
|
5834
|
+
).action(
|
|
5595
5835
|
async (cmdOpts) => {
|
|
5596
5836
|
process.exitCode = await devCommand({
|
|
5597
5837
|
...cmdOpts.dir !== void 0 ? { dir: cmdOpts.dir } : {},
|
|
@@ -5601,7 +5841,11 @@ program.command("dev").description(
|
|
|
5601
5841
|
...cmdOpts.apiUrl !== void 0 ? { apiUrl: cmdOpts.apiUrl } : {},
|
|
5602
5842
|
...cmdOpts.port !== void 0 ? { port: cmdOpts.port } : {},
|
|
5603
5843
|
...cmdOpts.sdkOnly !== void 0 ? { sdkOnly: cmdOpts.sdkOnly } : {},
|
|
5604
|
-
...cmdOpts.nextOnly !== void 0 ? { nextOnly: cmdOpts.nextOnly } : {}
|
|
5844
|
+
...cmdOpts.nextOnly !== void 0 ? { nextOnly: cmdOpts.nextOnly } : {},
|
|
5845
|
+
// Commander's --no-foo flag maps to `foo: false`. devCommand's
|
|
5846
|
+
// option is `noRemotePoll: boolean` — invert to map cleanly.
|
|
5847
|
+
...cmdOpts.remotePoll === false ? { noRemotePoll: true } : {},
|
|
5848
|
+
...cmdOpts.remotePollInterval !== void 0 ? { remotePollIntervalSec: cmdOpts.remotePollInterval } : {}
|
|
5605
5849
|
});
|
|
5606
5850
|
}
|
|
5607
5851
|
);
|
|
@@ -5753,6 +5997,14 @@ program.command("query").description(
|
|
|
5753
5997
|
});
|
|
5754
5998
|
}
|
|
5755
5999
|
);
|
|
6000
|
+
program.command("pull").description(
|
|
6001
|
+
"Sync local module.json from the backend. Fetches the canonical manifest for the current install and writes it to disk. Inverse of `dashwise table/field` commands."
|
|
6002
|
+
).option("--dir <path>", "Project root containing `module.json` (default: current directory).").option("--dry-run", "Fetch + report drift but do not write to module.json.").action(async (cmdOpts) => {
|
|
6003
|
+
process.exitCode = await pullCommand({
|
|
6004
|
+
...cmdOpts.dir !== void 0 ? { dir: cmdOpts.dir } : {},
|
|
6005
|
+
...cmdOpts.dryRun !== void 0 ? { dryRun: cmdOpts.dryRun } : {}
|
|
6006
|
+
});
|
|
6007
|
+
});
|
|
5756
6008
|
moduleCmd.command("publish").description("Pack the current directory + upload it as a new module version.").option("--dir <path>", "Project root (default: current directory).").option("--bump <direction>", "Semver bump: patch | minor | major.").option("--dry-run", "Validate + upload but do not persist the version row.").option("-y, --yes", "Skip the confirmation prompt (for CI / scripted use).").option(
|
|
5757
6009
|
"--exclude <pattern...>",
|
|
5758
6010
|
"Extra exclude patterns (segment-matched) appended to the defaults."
|
|
@@ -5944,7 +6196,7 @@ fieldCmd.command("set-type <table-slug> <field-slug> <new-type>").description(
|
|
|
5944
6196
|
}
|
|
5945
6197
|
})();
|
|
5946
6198
|
function getVersion() {
|
|
5947
|
-
return "0.
|
|
6199
|
+
return "0.4.0";
|
|
5948
6200
|
}
|
|
5949
6201
|
function parseIntOption(value) {
|
|
5950
6202
|
const n = Number.parseInt(value, 10);
|