newo 3.4.2 → 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 +21 -0
- package/dist/api.d.ts +18 -0
- package/dist/api.js +28 -0
- 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-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 +4 -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/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-new/bootstrap.ts +19 -7
- package/src/cli-new/di/tokens.ts +1 -0
- package/src/cli.ts +5 -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
|
@@ -46,7 +46,9 @@ import {
|
|
|
46
46
|
listFlowEvents,
|
|
47
47
|
listFlowStates,
|
|
48
48
|
updateSkill,
|
|
49
|
-
publishFlow
|
|
49
|
+
publishFlow,
|
|
50
|
+
listLibraries,
|
|
51
|
+
updateLibrarySkill,
|
|
50
52
|
} from '../../../api.js';
|
|
51
53
|
import {
|
|
52
54
|
ensureState,
|
|
@@ -60,7 +62,10 @@ import {
|
|
|
60
62
|
skillFolderPath,
|
|
61
63
|
flowsYamlPath,
|
|
62
64
|
customerProjectsDir,
|
|
63
|
-
projectDir
|
|
65
|
+
projectDir,
|
|
66
|
+
libraryMetadataPath,
|
|
67
|
+
librarySkillMetadataPath,
|
|
68
|
+
librarySkillScriptPath,
|
|
64
69
|
} from '../../../fsutil.js';
|
|
65
70
|
import { sha256, saveHashes, loadHashes } from '../../../hash.js';
|
|
66
71
|
import { generateFlowsYaml } from '../../../sync/metadata.js';
|
|
@@ -241,6 +246,52 @@ export class ProjectSyncStrategy implements ISyncStrategy<ProjectMeta, LocalProj
|
|
|
241
246
|
}
|
|
242
247
|
}
|
|
243
248
|
|
|
249
|
+
// Pull libraries for this project
|
|
250
|
+
try {
|
|
251
|
+
const libraries = await listLibraries(client, project.id);
|
|
252
|
+
if (libraries.length > 0) {
|
|
253
|
+
this.logger.verbose(` Found ${libraries.length} libraries in project ${project.idn}`);
|
|
254
|
+
projectData.libraries = {};
|
|
255
|
+
|
|
256
|
+
for (const lib of libraries) {
|
|
257
|
+
projectData.libraries[lib.idn] = {
|
|
258
|
+
id: lib.id,
|
|
259
|
+
skills: {}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// Save library metadata
|
|
263
|
+
const libMetaPath = libraryMetadataPath(customer.idn, project.idn, lib.idn);
|
|
264
|
+
const libMeta = { id: lib.id, idn: lib.idn };
|
|
265
|
+
const libMetaYaml = yaml.dump(libMeta, { indent: 2, quotingType: '"', forceQuotes: false });
|
|
266
|
+
await writeFileSafe(libMetaPath, libMetaYaml);
|
|
267
|
+
hashes[libMetaPath] = sha256(libMetaYaml);
|
|
268
|
+
|
|
269
|
+
for (const skill of lib.skills) {
|
|
270
|
+
// Save skill metadata
|
|
271
|
+
const skillMetaPath = librarySkillMetadataPath(customer.idn, project.idn, lib.idn, skill.idn);
|
|
272
|
+
const skillMeta: SkillMetadata = {
|
|
273
|
+
id: skill.id, idn: skill.idn, title: skill.title,
|
|
274
|
+
runner_type: skill.runner_type, model: skill.model,
|
|
275
|
+
parameters: [...skill.parameters], path: skill.path
|
|
276
|
+
};
|
|
277
|
+
const skillMetaYaml = yaml.dump(skillMeta, { indent: 2, quotingType: '"', forceQuotes: false });
|
|
278
|
+
await writeFileSafe(skillMetaPath, skillMetaYaml);
|
|
279
|
+
hashes[skillMetaPath] = sha256(skillMetaYaml);
|
|
280
|
+
|
|
281
|
+
// Save skill script
|
|
282
|
+
const scriptContent = skill.prompt_script || '';
|
|
283
|
+
const scriptPath = librarySkillScriptPath(customer.idn, project.idn, lib.idn, skill.idn, skill.runner_type);
|
|
284
|
+
await writeFileSafe(scriptPath, scriptContent);
|
|
285
|
+
hashes[scriptPath] = sha256(scriptContent);
|
|
286
|
+
|
|
287
|
+
projectData.libraries[lib.idn]!.skills[skill.idn] = skillMeta;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
} catch (error) {
|
|
292
|
+
this.logger.verbose(` Could not pull libraries for project ${project.idn}: ${error instanceof Error ? error.message : String(error)}`);
|
|
293
|
+
}
|
|
294
|
+
|
|
244
295
|
existingMap.projects[project.idn] = projectData;
|
|
245
296
|
projects.push(localProject);
|
|
246
297
|
}
|
|
@@ -489,11 +540,15 @@ export class ProjectSyncStrategy implements ISyncStrategy<ProjectMeta, LocalProj
|
|
|
489
540
|
for (const change of changes) {
|
|
490
541
|
try {
|
|
491
542
|
if (change.operation === 'modified') {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
543
|
+
const isLibrary = change.path.includes('/libraries/');
|
|
544
|
+
if (isLibrary) {
|
|
545
|
+
const updateResult = await this.pushLibrarySkillUpdate(client, change, mapData, newHashes);
|
|
546
|
+
result.updated += updateResult;
|
|
547
|
+
} else {
|
|
548
|
+
const updateResult = await this.pushSkillUpdate(client, customer, change, mapData, newHashes);
|
|
549
|
+
result.updated += updateResult;
|
|
550
|
+
}
|
|
495
551
|
} else if (change.operation === 'created') {
|
|
496
|
-
// Create new entity
|
|
497
552
|
const createResult = await this.pushNewEntity(client, customer, change, mapData, newHashes);
|
|
498
553
|
result.created += createResult;
|
|
499
554
|
}
|
|
@@ -563,6 +618,40 @@ export class ProjectSyncStrategy implements ISyncStrategy<ProjectMeta, LocalProj
|
|
|
563
618
|
return 1;
|
|
564
619
|
}
|
|
565
620
|
|
|
621
|
+
/**
|
|
622
|
+
* Push a library skill update
|
|
623
|
+
* Path: newo_customers/{customer}/projects/{project}/libraries/{lib}/{skill}/{skill}.jinja
|
|
624
|
+
*/
|
|
625
|
+
private async pushLibrarySkillUpdate(
|
|
626
|
+
client: AxiosInstance,
|
|
627
|
+
change: ChangeItem<LocalProjectData>,
|
|
628
|
+
mapData: ProjectMap,
|
|
629
|
+
newHashes: HashStore
|
|
630
|
+
): Promise<number> {
|
|
631
|
+
const pathParts = change.path.split('/');
|
|
632
|
+
const skillIdn = pathParts[pathParts.length - 2] || '';
|
|
633
|
+
const libIdn = pathParts[pathParts.length - 3] || '';
|
|
634
|
+
const projectIdn = pathParts[pathParts.length - 5] || '';
|
|
635
|
+
|
|
636
|
+
const projectData = mapData.projects[projectIdn];
|
|
637
|
+
const libData = projectData?.libraries?.[libIdn];
|
|
638
|
+
const skillData = libData?.skills[skillIdn];
|
|
639
|
+
|
|
640
|
+
if (!skillData || !libData) {
|
|
641
|
+
throw new Error(`Library skill ${skillIdn} not found in project map`);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const content = await fs.readFile(change.path, 'utf8');
|
|
645
|
+
|
|
646
|
+
await updateLibrarySkill(client, libData.id, skillData.id, {
|
|
647
|
+
prompt_script: content,
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
newHashes[change.path] = sha256(content);
|
|
651
|
+
this.logger.info(`Pushed library skill: ${libIdn}/${skillIdn}`);
|
|
652
|
+
return 1;
|
|
653
|
+
}
|
|
654
|
+
|
|
566
655
|
/**
|
|
567
656
|
* Push a new entity
|
|
568
657
|
*/
|
|
@@ -616,7 +705,7 @@ export class ProjectSyncStrategy implements ISyncStrategy<ProjectMeta, LocalProj
|
|
|
616
705
|
const hashes = await loadHashes(customer.idn);
|
|
617
706
|
const mapData = await fs.readJson(mapFile) as ProjectMap;
|
|
618
707
|
|
|
619
|
-
// Scan for changed skill scripts
|
|
708
|
+
// Scan for changed flow skill scripts
|
|
620
709
|
for (const [projectIdn, projectData] of Object.entries(mapData.projects)) {
|
|
621
710
|
for (const [agentIdn, agentData] of Object.entries(projectData.agents)) {
|
|
622
711
|
for (const [flowIdn, flowData] of Object.entries(agentData.flows)) {
|
|
@@ -629,7 +718,7 @@ export class ProjectSyncStrategy implements ISyncStrategy<ProjectMeta, LocalProj
|
|
|
629
718
|
|
|
630
719
|
if (storedHash !== currentHash) {
|
|
631
720
|
changes.push({
|
|
632
|
-
item: {} as LocalProjectData,
|
|
721
|
+
item: {} as LocalProjectData,
|
|
633
722
|
operation: 'modified',
|
|
634
723
|
path: skillFile.filePath
|
|
635
724
|
});
|
|
@@ -638,6 +727,31 @@ export class ProjectSyncStrategy implements ISyncStrategy<ProjectMeta, LocalProj
|
|
|
638
727
|
}
|
|
639
728
|
}
|
|
640
729
|
}
|
|
730
|
+
|
|
731
|
+
// Scan for changed library skill scripts
|
|
732
|
+
if (projectData.libraries) {
|
|
733
|
+
for (const [libIdn, libData] of Object.entries(projectData.libraries)) {
|
|
734
|
+
for (const [skillIdn, skillMeta] of Object.entries(libData.skills)) {
|
|
735
|
+
const scriptPath = librarySkillScriptPath(
|
|
736
|
+
customer.idn, projectIdn, libIdn, skillIdn, skillMeta.runner_type
|
|
737
|
+
);
|
|
738
|
+
|
|
739
|
+
if (await fs.pathExists(scriptPath)) {
|
|
740
|
+
const content = await fs.readFile(scriptPath, 'utf8');
|
|
741
|
+
const currentHash = sha256(content);
|
|
742
|
+
const storedHash = hashes[scriptPath];
|
|
743
|
+
|
|
744
|
+
if (storedHash !== currentHash) {
|
|
745
|
+
changes.push({
|
|
746
|
+
item: {} as LocalProjectData,
|
|
747
|
+
operation: 'modified',
|
|
748
|
+
path: scriptPath
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
641
755
|
}
|
|
642
756
|
|
|
643
757
|
return changes;
|