@xano/cli 1.0.4-beta.13 → 1.0.4-beta.17

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.
@@ -1,5 +1,6 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import BaseCommand from '../../../base-command.js';
3
+ import { pushKnowledge } from '../../../utils/knowledge-sync.js';
3
4
  export default class SandboxReset extends BaseCommand {
4
5
  static description = '[CRITICAL] NEVER run without explicit user confirmation; this clears all workspace data and drafts. Resets your sandbox environment.';
5
6
  static examples = [
@@ -42,6 +43,17 @@ Sandbox environment has been reset.
42
43
  const message = await this.parseApiError(response, 'API request failed');
43
44
  this.error(message);
44
45
  }
46
+ try {
47
+ const knowledgeUrl = `${profile.instance_origin}/api:meta/sandbox/knowledge/sync`;
48
+ await pushKnowledge(knowledgeUrl, profile.access_token, this.verboseFetch.bind(this), flags.verbose, {
49
+ delete: true,
50
+ force: true,
51
+ items: [],
52
+ });
53
+ }
54
+ catch (error) {
55
+ this.warn(`Sandbox environment was reset, but clearing knowledge files failed: ${error instanceof Error ? error.message : String(error)}`);
56
+ }
45
57
  this.log('Sandbox environment has been reset.');
46
58
  }
47
59
  catch (error) {
@@ -12,7 +12,7 @@ import { dirname, join, relative, sep } from 'node:path';
12
12
  // let the server dictate file paths.
13
13
  export const KNOWLEDGE_DIR = 'knowledge';
14
14
  // ── Frontmatter ──────────────────────────────────────────────────────────────
15
- const FRONTMATTER_ORDER = ['name', 'description', 'knowledge_type', 'scope', 'mode', 'enabled', 'guid'];
15
+ const FRONTMATTER_ORDER = ['name', 'description', 'knowledge_type', 'scope', 'inclusion', 'enabled', 'guid'];
16
16
  /**
17
17
  * Build a primary `.md` file body: YAML frontmatter (built from the object's
18
18
  * structured fields) followed by the markdown content.
@@ -26,7 +26,7 @@ export function buildPrimaryContent(obj) {
26
26
  if (obj.scope !== undefined)
27
27
  meta.scope = obj.scope;
28
28
  if (obj.mode !== undefined)
29
- meta.mode = obj.mode;
29
+ meta.inclusion = modeToInclusion(obj.mode);
30
30
  if (obj.enabled !== undefined)
31
31
  meta.enabled = obj.enabled;
32
32
  if (obj.guid !== undefined)
@@ -82,11 +82,13 @@ export function parseFrontmatter(content) {
82
82
  // ── Mode normalization ───────────────────────────────────────────────────────
83
83
  /**
84
84
  * The API only accepts the backend `mode` enum (`auto` | `referenced` | `always`),
85
- * but the Xano UI displays these as "On Demand" / "Manual" / "Always Included".
86
- * Hand-authored frontmatter (or content copied from the UI) commonly uses the
87
- * display label instead, which the API rejects with e.g. `Input "on demand" is
88
- * not one of the allowable values.` (DEV-7380/DEV-7382). Normalize known aliases
89
- * before every push so the backend enum value is always what's sent.
85
+ * but on disk (and in the Xano UI) this is the `inclusion` field with values
86
+ * "on demand" / "manual" / "always" — see `modeToInclusion` for the pull-side
87
+ * mapping. Hand-authored frontmatter (or content copied from the UI) commonly
88
+ * uses the display label instead, which the API rejects with e.g. `Input
89
+ * "on demand" is not one of the allowable values.` (DEV-7380/DEV-7382).
90
+ * Normalize known aliases before every push so the backend enum value is
91
+ * always what's sent.
90
92
  */
91
93
  const MODE_ALIASES = {
92
94
  'always included': 'always',
@@ -96,6 +98,15 @@ const MODE_ALIASES = {
96
98
  function normalizeMode(mode) {
97
99
  return MODE_ALIASES[mode.trim().toLowerCase()] ?? mode;
98
100
  }
101
+ /** Map the backend `mode` enum to the `inclusion:` frontmatter value shown in the Xano UI. */
102
+ const MODE_TO_INCLUSION = {
103
+ always: 'always',
104
+ auto: 'on demand',
105
+ referenced: 'manual',
106
+ };
107
+ function modeToInclusion(mode) {
108
+ return MODE_TO_INCLUSION[mode] ?? mode;
109
+ }
99
110
  // ── Path mapping (CLI-owned layout) ────────────────────────────────────────────
100
111
  /**
101
112
  * Allocate a unique snake_case folder/file segment per call, suffixing
@@ -222,13 +233,14 @@ export function collectKnowledgeObjects(inputDir, include, exclude) {
222
233
  : inferType(posixPath);
223
234
  // The API requires description/scope/mode/enabled on every item, so default
224
235
  // them when a hand-authored file omits them (pulled files always carry them).
236
+ // `mode` is read from the on-disk `inclusion:` field (see modeToInclusion).
225
237
  const obj = {
226
238
  content: body,
227
239
  description: typeof meta.description === 'string' ? meta.description : '',
228
240
  enabled: typeof meta.enabled === 'boolean' ? meta.enabled : true,
229
241
  filePath: absPath,
230
242
  knowledge_type: knowledgeType,
231
- mode: typeof meta.mode === 'string' ? normalizeMode(meta.mode) : 'auto',
243
+ mode: typeof meta.inclusion === 'string' ? normalizeMode(meta.inclusion) : 'auto',
232
244
  name: typeof meta.name === 'string' ? meta.name : deriveName(posixPath),
233
245
  scope: typeof meta.scope === 'string' ? meta.scope : 'workspace',
234
246
  };