newo 3.4.1 → 3.6.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/.env.example +5 -0
- package/CHANGELOG.md +31 -0
- package/dist/api.d.ts +18 -0
- package/dist/api.js +28 -0
- package/dist/cli/commands/create-attribute.js +1 -1
- package/dist/cli/commands/export.d.ts +3 -0
- package/dist/cli/commands/export.js +62 -0
- package/dist/cli/commands/help.js +54 -42
- package/dist/cli/commands/pull.js +38 -14
- package/dist/cli/commands/push.js +32 -32
- package/dist/cli/commands/status.js +46 -7
- package/dist/cli/commands/update-attribute.d.ts +3 -0
- package/dist/cli/commands/update-attribute.js +78 -0
- package/dist/cli-new/bootstrap.d.ts +7 -1
- package/dist/cli-new/bootstrap.js +11 -5
- package/dist/cli-new/di/tokens.d.ts +1 -0
- package/dist/cli-new/di/tokens.js +1 -0
- package/dist/cli.js +8 -0
- package/dist/domain/strategies/sync/ProjectSyncStrategy.d.ts +5 -0
- package/dist/domain/strategies/sync/ProjectSyncStrategy.js +97 -8
- package/dist/domain/strategies/sync/V2ProjectSyncStrategy.d.ts +80 -0
- package/dist/domain/strategies/sync/V2ProjectSyncStrategy.js +725 -0
- package/dist/env.d.ts +1 -0
- package/dist/env.js +1 -0
- package/dist/format/detect.d.ts +14 -0
- package/dist/format/detect.js +105 -0
- package/dist/format/extensions.d.ts +26 -0
- package/dist/format/extensions.js +45 -0
- package/dist/format/index.d.ts +11 -0
- package/dist/format/index.js +11 -0
- package/dist/format/paths-v2.d.ts +31 -0
- package/dist/format/paths-v2.js +104 -0
- package/dist/format/types.d.ts +28 -0
- package/dist/format/types.js +21 -0
- package/dist/format/v2-yaml.d.ts +143 -0
- package/dist/format/v2-yaml.js +222 -0
- package/dist/format/yaml-patch.d.ts +14 -0
- package/dist/format/yaml-patch.js +184 -0
- package/dist/fsutil.d.ts +10 -0
- package/dist/fsutil.js +25 -0
- package/dist/sync/attributes.js +3 -3
- package/dist/sync/skill-files.js +2 -2
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
- package/src/api.ts +64 -0
- package/src/cli/commands/create-attribute.ts +1 -1
- package/src/cli/commands/export.ts +78 -0
- package/src/cli/commands/help.ts +54 -42
- package/src/cli/commands/pull.ts +46 -15
- package/src/cli/commands/push.ts +38 -31
- package/src/cli/commands/status.ts +59 -9
- package/src/cli/commands/update-attribute.ts +82 -0
- package/src/cli-new/bootstrap.ts +19 -7
- package/src/cli-new/di/tokens.ts +1 -0
- package/src/cli.ts +10 -0
- package/src/domain/strategies/sync/ProjectSyncStrategy.ts +122 -8
- package/src/domain/strategies/sync/V2ProjectSyncStrategy.ts +1007 -0
- package/src/env.ts +2 -0
- package/src/format/detect.ts +123 -0
- package/src/format/extensions.ts +61 -0
- package/src/format/index.ts +66 -0
- package/src/format/paths-v2.ts +207 -0
- package/src/format/types.ts +40 -0
- package/src/format/v2-yaml.ts +345 -0
- package/src/format/yaml-patch.ts +208 -0
- package/src/fsutil.ts +37 -0
- package/src/sync/attributes.ts +3 -3
- package/src/sync/skill-files.ts +2 -2
- package/src/types.ts +6 -0
package/src/env.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface ValidatedEnv {
|
|
|
12
12
|
readonly NEWO_REFRESH_TOKEN: string | undefined;
|
|
13
13
|
readonly NEWO_REFRESH_URL: string | undefined;
|
|
14
14
|
readonly NEWO_DEFAULT_CUSTOMER: string | undefined;
|
|
15
|
+
readonly NEWO_FORMAT: string | undefined;
|
|
15
16
|
// Dynamic customer entries will be detected at runtime
|
|
16
17
|
readonly [key: string]: string | undefined;
|
|
17
18
|
}
|
|
@@ -81,6 +82,7 @@ export function validateEnvironment(): ValidatedEnv {
|
|
|
81
82
|
NEWO_REFRESH_TOKEN: refreshToken,
|
|
82
83
|
NEWO_REFRESH_URL: refreshUrl,
|
|
83
84
|
NEWO_DEFAULT_CUSTOMER: env.NEWO_DEFAULT_CUSTOMER?.trim(),
|
|
85
|
+
NEWO_FORMAT: env.NEWO_FORMAT?.trim(),
|
|
84
86
|
};
|
|
85
87
|
}
|
|
86
88
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format detection and resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolution chain per customer (highest to lowest priority):
|
|
5
|
+
* 1. Explicit --format flag (per-command override)
|
|
6
|
+
* 2. Filesystem auto-detect (for EXISTING customers):
|
|
7
|
+
* - import_version.txt present -> newo_v2
|
|
8
|
+
* - projects/ directory present -> cli_v1
|
|
9
|
+
* 3. NEWO_FORMAT env var (only for NEW customers where nothing exists locally)
|
|
10
|
+
* 4. Default: cli_v1
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'fs-extra';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { NEWO_CUSTOMERS_DIR } from '../fsutil.js';
|
|
15
|
+
import { type FormatVersion, type FormatConfig, VALID_FORMATS } from './types.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Detect format from existing filesystem structure for a customer
|
|
19
|
+
* Returns null if the customer directory doesn't exist or is empty
|
|
20
|
+
*/
|
|
21
|
+
export function detectFormatFromFilesystem(customerIdn: string): FormatVersion | null {
|
|
22
|
+
const customerDir = path.join(NEWO_CUSTOMERS_DIR, customerIdn);
|
|
23
|
+
|
|
24
|
+
if (!fs.existsSync(customerDir)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check for V2 marker: import_version.txt
|
|
29
|
+
const importVersionFile = path.join(customerDir, 'import_version.txt');
|
|
30
|
+
if (fs.existsSync(importVersionFile)) {
|
|
31
|
+
return 'newo_v2';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Check for V1 marker: projects/ directory
|
|
35
|
+
const projectsDir = path.join(customerDir, 'projects');
|
|
36
|
+
if (fs.existsSync(projectsDir)) {
|
|
37
|
+
return 'cli_v1';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check one level down for import_version.txt (V2 exports sometimes have a wrapper dir)
|
|
41
|
+
try {
|
|
42
|
+
const entries = fs.readdirSync(customerDir, { withFileTypes: true });
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
if (entry.isDirectory()) {
|
|
45
|
+
const nestedImportVersion = path.join(customerDir, entry.name, 'import_version.txt');
|
|
46
|
+
if (fs.existsSync(nestedImportVersion)) {
|
|
47
|
+
return 'newo_v2';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
// Ignore read errors
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Directory exists but no format markers found - could be empty or only has attributes
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get format from NEWO_FORMAT environment variable
|
|
61
|
+
*/
|
|
62
|
+
function getEnvFormat(): FormatVersion | null {
|
|
63
|
+
const envFormat = process.env['NEWO_FORMAT']?.trim().toLowerCase();
|
|
64
|
+
if (!envFormat) return null;
|
|
65
|
+
|
|
66
|
+
if ((VALID_FORMATS as readonly string[]).includes(envFormat)) {
|
|
67
|
+
return envFormat as FormatVersion;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.warn(
|
|
71
|
+
`Warning: Invalid NEWO_FORMAT="${envFormat}". Valid values: ${VALID_FORMATS.join(', ')}. Using default.`
|
|
72
|
+
);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate an explicit format string from --format flag
|
|
78
|
+
*/
|
|
79
|
+
function validateExplicitFormat(format: string): FormatVersion | null {
|
|
80
|
+
const normalized = format.trim().toLowerCase();
|
|
81
|
+
if ((VALID_FORMATS as readonly string[]).includes(normalized)) {
|
|
82
|
+
return normalized as FormatVersion;
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Resolve the format version for a customer using the full resolution chain
|
|
89
|
+
*
|
|
90
|
+
* @param customerIdn - Customer identifier
|
|
91
|
+
* @param explicitFormat - Optional --format flag value
|
|
92
|
+
*/
|
|
93
|
+
export function resolveFormat(
|
|
94
|
+
customerIdn: string,
|
|
95
|
+
explicitFormat?: string
|
|
96
|
+
): FormatConfig {
|
|
97
|
+
// 1. Explicit --format flag takes highest priority
|
|
98
|
+
if (explicitFormat) {
|
|
99
|
+
const validated = validateExplicitFormat(explicitFormat);
|
|
100
|
+
if (validated) {
|
|
101
|
+
return { version: validated, source: 'explicit-flag' };
|
|
102
|
+
}
|
|
103
|
+
console.error(
|
|
104
|
+
`Invalid format "${explicitFormat}". Valid values: ${VALID_FORMATS.join(', ')}`
|
|
105
|
+
);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 2. Filesystem auto-detect for existing customers
|
|
110
|
+
const detected = detectFormatFromFilesystem(customerIdn);
|
|
111
|
+
if (detected) {
|
|
112
|
+
return { version: detected, source: 'auto-detected' };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 3. NEWO_FORMAT env var (for new customers only)
|
|
116
|
+
const envFormat = getEnvFormat();
|
|
117
|
+
if (envFormat) {
|
|
118
|
+
return { version: envFormat, source: 'env-var' };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 4. Default: cli_v1
|
|
122
|
+
return { version: 'cli_v1', source: 'default' };
|
|
123
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format-aware file extension mapping
|
|
3
|
+
*
|
|
4
|
+
* Handles the extension differences between cli_v1 and newo_v2:
|
|
5
|
+
* cli_v1: guidance -> .guidance, nsl -> .jinja
|
|
6
|
+
* newo_v2: guidance -> .nslg, nsl -> .nsl
|
|
7
|
+
*/
|
|
8
|
+
import type { RunnerType } from '../types.js';
|
|
9
|
+
import {
|
|
10
|
+
type FormatVersion,
|
|
11
|
+
CLI_V1_EXTENSIONS,
|
|
12
|
+
NEWO_V2_EXTENSIONS,
|
|
13
|
+
ALL_SCRIPT_EXTENSIONS,
|
|
14
|
+
} from './types.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get file extension for a runner type in a specific format
|
|
18
|
+
*/
|
|
19
|
+
export function getExtensionForFormat(runnerType: RunnerType, format: FormatVersion): string {
|
|
20
|
+
const map = format === 'newo_v2' ? NEWO_V2_EXTENSIONS : CLI_V1_EXTENSIONS;
|
|
21
|
+
const ext = map[runnerType];
|
|
22
|
+
return ext ?? CLI_V1_EXTENSIONS.guidance;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get runner type from file extension (works for all 4 extensions)
|
|
27
|
+
*/
|
|
28
|
+
export function getRunnerTypeFromExtension(ext: string): RunnerType {
|
|
29
|
+
const normalized = ext.startsWith('.') ? ext : `.${ext}`;
|
|
30
|
+
switch (normalized) {
|
|
31
|
+
case '.guidance':
|
|
32
|
+
case '.nslg':
|
|
33
|
+
return 'guidance';
|
|
34
|
+
case '.jinja':
|
|
35
|
+
case '.nsl':
|
|
36
|
+
return 'nsl';
|
|
37
|
+
default:
|
|
38
|
+
return 'guidance';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check if a filename is a recognized script file (any format)
|
|
44
|
+
*/
|
|
45
|
+
export function isScriptFile(filename: string): boolean {
|
|
46
|
+
const ext = filename.lastIndexOf('.') >= 0
|
|
47
|
+
? filename.slice(filename.lastIndexOf('.'))
|
|
48
|
+
: '';
|
|
49
|
+
return (ALL_SCRIPT_EXTENSIONS as readonly string[]).includes(ext.toLowerCase());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Infer format version from a file extension
|
|
54
|
+
*/
|
|
55
|
+
export function getFormatFromExtension(ext: string): FormatVersion {
|
|
56
|
+
const normalized = ext.startsWith('.') ? ext : `.${ext}`;
|
|
57
|
+
if (normalized === '.nsl' || normalized === '.nslg') {
|
|
58
|
+
return 'newo_v2';
|
|
59
|
+
}
|
|
60
|
+
return 'cli_v1';
|
|
61
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format module - handles cli_v1 and newo_v2 format differences
|
|
3
|
+
*/
|
|
4
|
+
export {
|
|
5
|
+
type FormatVersion,
|
|
6
|
+
type FormatConfig,
|
|
7
|
+
CLI_V1_EXTENSIONS,
|
|
8
|
+
NEWO_V2_EXTENSIONS,
|
|
9
|
+
ALL_SCRIPT_EXTENSIONS,
|
|
10
|
+
V2_IMPORT_VERSION,
|
|
11
|
+
VALID_FORMATS,
|
|
12
|
+
} from './types.js';
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
getExtensionForFormat,
|
|
16
|
+
getRunnerTypeFromExtension,
|
|
17
|
+
isScriptFile,
|
|
18
|
+
getFormatFromExtension,
|
|
19
|
+
} from './extensions.js';
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
detectFormatFromFilesystem,
|
|
23
|
+
resolveFormat,
|
|
24
|
+
} from './detect.js';
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
v2CustomerDir,
|
|
28
|
+
v2ProjectDir,
|
|
29
|
+
v2AgentDir,
|
|
30
|
+
v2FlowDir,
|
|
31
|
+
v2SkillsDir,
|
|
32
|
+
v2SkillScriptPath,
|
|
33
|
+
v2FlowYamlPath,
|
|
34
|
+
v2ProjectYamlPath,
|
|
35
|
+
v2AgentYamlPath,
|
|
36
|
+
v2ImportVersionPath,
|
|
37
|
+
v2AkbDir,
|
|
38
|
+
v2AkbPath,
|
|
39
|
+
v2CustomerAttributesPath,
|
|
40
|
+
v2ProjectAttributesPath,
|
|
41
|
+
v2LibraryDir,
|
|
42
|
+
v2LibraryYamlPath,
|
|
43
|
+
v2LibrarySkillsDir,
|
|
44
|
+
v2LibrarySkillScriptPath,
|
|
45
|
+
} from './paths-v2.js';
|
|
46
|
+
|
|
47
|
+
export { patchYamlToPyyaml } from './yaml-patch.js';
|
|
48
|
+
export { v2LibrarySkillRelativePath } from './paths-v2.js';
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
type V2FlowDefinition,
|
|
52
|
+
type V2InlineSkill,
|
|
53
|
+
type V2FlowEvent,
|
|
54
|
+
type V2StateField,
|
|
55
|
+
type V2ProjectMeta,
|
|
56
|
+
type V2AgentMeta,
|
|
57
|
+
type V2LibraryDefinition,
|
|
58
|
+
parseV2FlowYaml,
|
|
59
|
+
generateV2FlowYaml,
|
|
60
|
+
parseV2ProjectYaml,
|
|
61
|
+
generateV2ProjectYaml,
|
|
62
|
+
parseV2AgentYaml,
|
|
63
|
+
generateV2AgentYaml,
|
|
64
|
+
parseV2LibraryYaml,
|
|
65
|
+
generateV2LibraryYaml,
|
|
66
|
+
} from './v2-yaml.js';
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V2 (newo_v2) path utilities
|
|
3
|
+
*
|
|
4
|
+
* Generates paths for the NEWO platform export format:
|
|
5
|
+
* newo_customers/{cust}/
|
|
6
|
+
* import_version.txt
|
|
7
|
+
* attributes.yaml
|
|
8
|
+
* akb/{AgentIdn}.yaml
|
|
9
|
+
* {ProjectIdn}/
|
|
10
|
+
* {project_idn}.yaml
|
|
11
|
+
* attributes.yaml
|
|
12
|
+
* agents/{AgentIdn}/
|
|
13
|
+
* agent.yaml
|
|
14
|
+
* flows/{FlowIdn}/
|
|
15
|
+
* {FlowIdn}.yaml
|
|
16
|
+
* skills/{SkillIdn}.nsl|.nslg
|
|
17
|
+
* libraries/{LibIdn}/
|
|
18
|
+
* {lib_idn}.yaml
|
|
19
|
+
* skills/{SkillIdn}.nsl|.nslg
|
|
20
|
+
*/
|
|
21
|
+
import path from 'path';
|
|
22
|
+
import { NEWO_CUSTOMERS_DIR } from '../fsutil.js';
|
|
23
|
+
import type { RunnerType } from '../types.js';
|
|
24
|
+
import { getExtensionForFormat } from './extensions.js';
|
|
25
|
+
|
|
26
|
+
// ── Customer level ──
|
|
27
|
+
|
|
28
|
+
export function v2CustomerDir(customerIdn: string): string {
|
|
29
|
+
return path.posix.join(NEWO_CUSTOMERS_DIR, customerIdn);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function v2ImportVersionPath(customerIdn: string): string {
|
|
33
|
+
return path.posix.join(v2CustomerDir(customerIdn), 'import_version.txt');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function v2CustomerAttributesPath(customerIdn: string): string {
|
|
37
|
+
return path.posix.join(v2CustomerDir(customerIdn), 'attributes.yaml');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ── AKB level ──
|
|
41
|
+
|
|
42
|
+
export function v2AkbDir(customerIdn: string): string {
|
|
43
|
+
return path.posix.join(v2CustomerDir(customerIdn), 'akb');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function v2AkbPath(customerIdn: string, agentIdn: string): string {
|
|
47
|
+
return path.posix.join(v2AkbDir(customerIdn), `${agentIdn}.yaml`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ── Project level ──
|
|
51
|
+
|
|
52
|
+
export function v2ProjectDir(customerIdn: string, projectIdn: string): string {
|
|
53
|
+
return path.posix.join(v2CustomerDir(customerIdn), projectIdn);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function v2ProjectYamlPath(customerIdn: string, projectIdn: string): string {
|
|
57
|
+
return path.posix.join(v2ProjectDir(customerIdn, projectIdn), `${projectIdn}.yaml`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function v2ProjectAttributesPath(customerIdn: string, projectIdn: string): string {
|
|
61
|
+
return path.posix.join(v2ProjectDir(customerIdn, projectIdn), 'attributes.yaml');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ── Agent level ──
|
|
65
|
+
|
|
66
|
+
export function v2AgentDir(
|
|
67
|
+
customerIdn: string,
|
|
68
|
+
projectIdn: string,
|
|
69
|
+
agentIdn: string
|
|
70
|
+
): string {
|
|
71
|
+
return path.posix.join(v2ProjectDir(customerIdn, projectIdn), 'agents', agentIdn);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function v2AgentYamlPath(
|
|
75
|
+
customerIdn: string,
|
|
76
|
+
projectIdn: string,
|
|
77
|
+
agentIdn: string
|
|
78
|
+
): string {
|
|
79
|
+
return path.posix.join(v2AgentDir(customerIdn, projectIdn, agentIdn), 'agent.yaml');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ── Flow level ──
|
|
83
|
+
|
|
84
|
+
export function v2FlowDir(
|
|
85
|
+
customerIdn: string,
|
|
86
|
+
projectIdn: string,
|
|
87
|
+
agentIdn: string,
|
|
88
|
+
flowIdn: string
|
|
89
|
+
): string {
|
|
90
|
+
return path.posix.join(
|
|
91
|
+
v2AgentDir(customerIdn, projectIdn, agentIdn),
|
|
92
|
+
'flows',
|
|
93
|
+
flowIdn
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function v2FlowYamlPath(
|
|
98
|
+
customerIdn: string,
|
|
99
|
+
projectIdn: string,
|
|
100
|
+
agentIdn: string,
|
|
101
|
+
flowIdn: string
|
|
102
|
+
): string {
|
|
103
|
+
return path.posix.join(
|
|
104
|
+
v2FlowDir(customerIdn, projectIdn, agentIdn, flowIdn),
|
|
105
|
+
`${flowIdn}.yaml`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ── Skill level ──
|
|
110
|
+
|
|
111
|
+
export function v2SkillsDir(
|
|
112
|
+
customerIdn: string,
|
|
113
|
+
projectIdn: string,
|
|
114
|
+
agentIdn: string,
|
|
115
|
+
flowIdn: string
|
|
116
|
+
): string {
|
|
117
|
+
return path.posix.join(
|
|
118
|
+
v2FlowDir(customerIdn, projectIdn, agentIdn, flowIdn),
|
|
119
|
+
'skills'
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function v2SkillScriptPath(
|
|
124
|
+
customerIdn: string,
|
|
125
|
+
projectIdn: string,
|
|
126
|
+
agentIdn: string,
|
|
127
|
+
flowIdn: string,
|
|
128
|
+
skillIdn: string,
|
|
129
|
+
runnerType: RunnerType
|
|
130
|
+
): string {
|
|
131
|
+
const ext = getExtensionForFormat(runnerType, 'newo_v2');
|
|
132
|
+
return path.posix.join(
|
|
133
|
+
v2SkillsDir(customerIdn, projectIdn, agentIdn, flowIdn),
|
|
134
|
+
`${skillIdn}${ext}`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Build the relative prompt_script path as it appears in V2 flow YAML
|
|
140
|
+
* e.g., "flows/MainFlow/skills/GreetingSkill.nsl"
|
|
141
|
+
*/
|
|
142
|
+
export function v2SkillRelativePath(
|
|
143
|
+
flowIdn: string,
|
|
144
|
+
skillIdn: string,
|
|
145
|
+
runnerType: RunnerType
|
|
146
|
+
): string {
|
|
147
|
+
const ext = getExtensionForFormat(runnerType, 'newo_v2');
|
|
148
|
+
return `flows/${flowIdn}/skills/${skillIdn}${ext}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ── Library level ──
|
|
152
|
+
|
|
153
|
+
export function v2LibraryDir(
|
|
154
|
+
customerIdn: string,
|
|
155
|
+
projectIdn: string,
|
|
156
|
+
libraryIdn: string
|
|
157
|
+
): string {
|
|
158
|
+
return path.posix.join(v2ProjectDir(customerIdn, projectIdn), 'libraries', libraryIdn);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function v2LibraryYamlPath(
|
|
162
|
+
customerIdn: string,
|
|
163
|
+
projectIdn: string,
|
|
164
|
+
libraryIdn: string
|
|
165
|
+
): string {
|
|
166
|
+
return path.posix.join(
|
|
167
|
+
v2LibraryDir(customerIdn, projectIdn, libraryIdn),
|
|
168
|
+
`${libraryIdn}.yaml`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function v2LibrarySkillsDir(
|
|
173
|
+
customerIdn: string,
|
|
174
|
+
projectIdn: string,
|
|
175
|
+
libraryIdn: string
|
|
176
|
+
): string {
|
|
177
|
+
return path.posix.join(v2LibraryDir(customerIdn, projectIdn, libraryIdn), 'skills');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function v2LibrarySkillScriptPath(
|
|
181
|
+
customerIdn: string,
|
|
182
|
+
projectIdn: string,
|
|
183
|
+
libraryIdn: string,
|
|
184
|
+
skillIdn: string,
|
|
185
|
+
runnerType: RunnerType
|
|
186
|
+
): string {
|
|
187
|
+
const ext = getExtensionForFormat(runnerType, 'newo_v2');
|
|
188
|
+
return path.posix.join(
|
|
189
|
+
v2LibrarySkillsDir(customerIdn, projectIdn, libraryIdn),
|
|
190
|
+
`${skillIdn}${ext}`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Build relative prompt_script path for library skill in V2 YAML
|
|
196
|
+
* The V2 export includes the project prefix:
|
|
197
|
+
* e.g., "naf/libraries/testLib/skills/utilSkill.nsl"
|
|
198
|
+
*/
|
|
199
|
+
export function v2LibrarySkillRelativePath(
|
|
200
|
+
projectIdn: string,
|
|
201
|
+
libraryIdn: string,
|
|
202
|
+
skillIdn: string,
|
|
203
|
+
runnerType: RunnerType
|
|
204
|
+
): string {
|
|
205
|
+
const ext = getExtensionForFormat(runnerType, 'newo_v2');
|
|
206
|
+
return `${projectIdn}/libraries/${libraryIdn}/skills/${skillIdn}${ext}`;
|
|
207
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format version types and constants
|
|
3
|
+
*
|
|
4
|
+
* Defines the two supported project formats:
|
|
5
|
+
* - cli_v1: Native CLI format (full feature support, per-entity metadata)
|
|
6
|
+
* - newo_v2: NEWO platform export format (compatible with platform UI exports)
|
|
7
|
+
*/
|
|
8
|
+
import type { RunnerType } from '../types.js';
|
|
9
|
+
|
|
10
|
+
export type FormatVersion = 'cli_v1' | 'newo_v2';
|
|
11
|
+
|
|
12
|
+
export interface FormatConfig {
|
|
13
|
+
version: FormatVersion;
|
|
14
|
+
source: 'explicit-flag' | 'env-var' | 'auto-detected' | 'default';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Extension mapping per format
|
|
19
|
+
*
|
|
20
|
+
* cli_v1: guidance -> .guidance, nsl -> .jinja
|
|
21
|
+
* newo_v2: guidance -> .nslg, nsl -> .nsl
|
|
22
|
+
*/
|
|
23
|
+
export const CLI_V1_EXTENSIONS: Record<RunnerType, string> = {
|
|
24
|
+
guidance: '.guidance',
|
|
25
|
+
nsl: '.jinja',
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
export const NEWO_V2_EXTENSIONS: Record<RunnerType, string> = {
|
|
29
|
+
guidance: '.nslg',
|
|
30
|
+
nsl: '.nsl',
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
33
|
+
/** All recognized script file extensions across both formats */
|
|
34
|
+
export const ALL_SCRIPT_EXTENSIONS = ['.guidance', '.jinja', '.nsl', '.nslg'] as const;
|
|
35
|
+
|
|
36
|
+
/** V2 import version marker content */
|
|
37
|
+
export const V2_IMPORT_VERSION = 'v2.0.0';
|
|
38
|
+
|
|
39
|
+
/** Valid format values for CLI flag and env var validation */
|
|
40
|
+
export const VALID_FORMATS: readonly FormatVersion[] = ['cli_v1', 'newo_v2'] as const;
|