newo 1.4.0 → 1.5.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/CHANGELOG.md +41 -0
- package/README.md +41 -1
- package/dist/akb.d.ts +10 -0
- package/dist/akb.js +84 -0
- package/dist/api.d.ts +13 -0
- package/dist/api.js +100 -0
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +104 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +111 -0
- package/dist/fsutil.d.ts +12 -0
- package/dist/fsutil.js +28 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.js +17 -0
- package/dist/sync.d.ts +7 -0
- package/dist/sync.js +337 -0
- package/dist/types.d.ts +206 -0
- package/dist/types.js +5 -0
- package/package.json +26 -12
- package/src/{akb.js → akb.ts} +16 -25
- package/src/api.ts +127 -0
- package/src/auth.ts +142 -0
- package/src/{cli.js → cli.ts} +17 -10
- package/src/{fsutil.js → fsutil.ts} +14 -7
- package/src/hash.ts +20 -0
- package/src/{sync.js → sync.ts} +91 -44
- package/src/types.ts +248 -0
- package/src/api.js +0 -103
- package/src/auth.js +0 -92
- package/src/hash.js +0 -17
package/dist/sync.js
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { listProjects, listAgents, listFlowSkills, updateSkill, listFlowEvents, listFlowStates, getProjectMeta } from './api.js';
|
|
2
|
+
import { ensureState, skillPath, writeFileAtomic, readIfExists, MAP_PATH, projectDir, metadataPath } from './fsutil.js';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import { sha256, loadHashes, saveHashes } from './hash.js';
|
|
5
|
+
import yaml from 'js-yaml';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
export async function pullSingleProject(client, projectId, projectIdn, verbose = false) {
|
|
8
|
+
if (verbose)
|
|
9
|
+
console.log(`🔍 Fetching agents for project ${projectId} (${projectIdn})...`);
|
|
10
|
+
const agents = await listAgents(client, projectId);
|
|
11
|
+
if (verbose)
|
|
12
|
+
console.log(`📦 Found ${agents.length} agents`);
|
|
13
|
+
// Get and save project metadata
|
|
14
|
+
const projectMeta = await getProjectMeta(client, projectId);
|
|
15
|
+
await writeFileAtomic(metadataPath(projectIdn), JSON.stringify(projectMeta, null, 2));
|
|
16
|
+
if (verbose)
|
|
17
|
+
console.log(`✓ Saved metadata for ${projectIdn}`);
|
|
18
|
+
const projectMap = { projectId, projectIdn, agents: {} };
|
|
19
|
+
for (const agent of agents) {
|
|
20
|
+
const aKey = agent.idn;
|
|
21
|
+
projectMap.agents[aKey] = { id: agent.id, flows: {} };
|
|
22
|
+
for (const flow of agent.flows ?? []) {
|
|
23
|
+
projectMap.agents[aKey].flows[flow.idn] = { id: flow.id, skills: {} };
|
|
24
|
+
const skills = await listFlowSkills(client, flow.id);
|
|
25
|
+
for (const skill of skills) {
|
|
26
|
+
const file = skillPath(projectIdn, agent.idn, flow.idn, skill.idn, skill.runner_type);
|
|
27
|
+
await writeFileAtomic(file, skill.prompt_script || '');
|
|
28
|
+
// Store complete skill metadata for push operations
|
|
29
|
+
projectMap.agents[aKey].flows[flow.idn].skills[skill.idn] = {
|
|
30
|
+
id: skill.id,
|
|
31
|
+
title: skill.title,
|
|
32
|
+
idn: skill.idn,
|
|
33
|
+
runner_type: skill.runner_type,
|
|
34
|
+
model: skill.model,
|
|
35
|
+
parameters: skill.parameters,
|
|
36
|
+
path: skill.path || undefined
|
|
37
|
+
};
|
|
38
|
+
console.log(`✓ Pulled ${file}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Generate flows.yaml for this project
|
|
43
|
+
if (verbose)
|
|
44
|
+
console.log(`📄 Generating flows.yaml for ${projectIdn}...`);
|
|
45
|
+
await generateFlowsYaml(client, agents, projectIdn, verbose);
|
|
46
|
+
return projectMap;
|
|
47
|
+
}
|
|
48
|
+
export async function pullAll(client, projectId = null, verbose = false) {
|
|
49
|
+
await ensureState();
|
|
50
|
+
if (projectId) {
|
|
51
|
+
// Single project mode
|
|
52
|
+
const projectMeta = await getProjectMeta(client, projectId);
|
|
53
|
+
const projectMap = await pullSingleProject(client, projectId, projectMeta.idn, verbose);
|
|
54
|
+
const idMap = { projects: { [projectMeta.idn]: projectMap } };
|
|
55
|
+
await fs.writeJson(MAP_PATH, idMap, { spaces: 2 });
|
|
56
|
+
// Generate hash tracking for this project
|
|
57
|
+
const hashes = {};
|
|
58
|
+
for (const [agentIdn, agentObj] of Object.entries(projectMap.agents)) {
|
|
59
|
+
for (const [flowIdn, flowObj] of Object.entries(agentObj.flows)) {
|
|
60
|
+
for (const [skillIdn, skillMeta] of Object.entries(flowObj.skills)) {
|
|
61
|
+
const p = skillPath(projectMeta.idn, agentIdn, flowIdn, skillIdn, skillMeta.runner_type);
|
|
62
|
+
const content = await fs.readFile(p, 'utf8');
|
|
63
|
+
hashes[p] = sha256(content);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
await saveHashes(hashes);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Multi-project mode
|
|
71
|
+
if (verbose)
|
|
72
|
+
console.log('🔍 Fetching all projects...');
|
|
73
|
+
const projects = await listProjects(client);
|
|
74
|
+
if (verbose)
|
|
75
|
+
console.log(`📦 Found ${projects.length} projects`);
|
|
76
|
+
const idMap = { projects: {} };
|
|
77
|
+
const allHashes = {};
|
|
78
|
+
for (const project of projects) {
|
|
79
|
+
if (verbose)
|
|
80
|
+
console.log(`\n📁 Processing project: ${project.idn} (${project.title})`);
|
|
81
|
+
const projectMap = await pullSingleProject(client, project.id, project.idn, verbose);
|
|
82
|
+
idMap.projects[project.idn] = projectMap;
|
|
83
|
+
// Collect hashes for this project
|
|
84
|
+
for (const [agentIdn, agentObj] of Object.entries(projectMap.agents)) {
|
|
85
|
+
for (const [flowIdn, flowObj] of Object.entries(agentObj.flows)) {
|
|
86
|
+
for (const [skillIdn, skillMeta] of Object.entries(flowObj.skills)) {
|
|
87
|
+
const p = skillPath(project.idn, agentIdn, flowIdn, skillIdn, skillMeta.runner_type);
|
|
88
|
+
const content = await fs.readFile(p, 'utf8');
|
|
89
|
+
allHashes[p] = sha256(content);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
await fs.writeJson(MAP_PATH, idMap, { spaces: 2 });
|
|
95
|
+
await saveHashes(allHashes);
|
|
96
|
+
}
|
|
97
|
+
export async function pushChanged(client, verbose = false) {
|
|
98
|
+
await ensureState();
|
|
99
|
+
if (!(await fs.pathExists(MAP_PATH))) {
|
|
100
|
+
throw new Error('Missing .newo/map.json. Run `newo pull` first.');
|
|
101
|
+
}
|
|
102
|
+
if (verbose)
|
|
103
|
+
console.log('📋 Loading project mapping...');
|
|
104
|
+
const idMap = await fs.readJson(MAP_PATH);
|
|
105
|
+
if (verbose)
|
|
106
|
+
console.log('🔍 Loading file hashes...');
|
|
107
|
+
const oldHashes = await loadHashes();
|
|
108
|
+
const newHashes = { ...oldHashes };
|
|
109
|
+
if (verbose)
|
|
110
|
+
console.log('🔄 Scanning for changes...');
|
|
111
|
+
let pushed = 0;
|
|
112
|
+
let scanned = 0;
|
|
113
|
+
// Handle both old single-project format and new multi-project format
|
|
114
|
+
const projects = 'projects' in idMap && idMap.projects ? idMap.projects : { '': idMap };
|
|
115
|
+
for (const [projectIdn, projectData] of Object.entries(projects)) {
|
|
116
|
+
if (verbose && projectIdn)
|
|
117
|
+
console.log(`📁 Scanning project: ${projectIdn}`);
|
|
118
|
+
for (const [agentIdn, agentObj] of Object.entries(projectData.agents)) {
|
|
119
|
+
if (verbose)
|
|
120
|
+
console.log(` 📁 Scanning agent: ${agentIdn}`);
|
|
121
|
+
for (const [flowIdn, flowObj] of Object.entries(agentObj.flows)) {
|
|
122
|
+
if (verbose)
|
|
123
|
+
console.log(` 📁 Scanning flow: ${flowIdn}`);
|
|
124
|
+
for (const [skillIdn, skillMeta] of Object.entries(flowObj.skills)) {
|
|
125
|
+
const p = projectIdn ?
|
|
126
|
+
skillPath(projectIdn, agentIdn, flowIdn, skillIdn, skillMeta.runner_type) :
|
|
127
|
+
skillPath('', agentIdn, flowIdn, skillIdn, skillMeta.runner_type);
|
|
128
|
+
scanned++;
|
|
129
|
+
if (verbose)
|
|
130
|
+
console.log(` 📄 Checking: ${p}`);
|
|
131
|
+
const content = await readIfExists(p);
|
|
132
|
+
if (content === null) {
|
|
133
|
+
if (verbose)
|
|
134
|
+
console.log(` ⚠️ File not found: ${p}`);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const h = sha256(content);
|
|
138
|
+
const oldHash = oldHashes[p];
|
|
139
|
+
if (verbose) {
|
|
140
|
+
console.log(` 🔍 Hash comparison:`);
|
|
141
|
+
console.log(` Old: ${oldHash || 'none'}`);
|
|
142
|
+
console.log(` New: ${h}`);
|
|
143
|
+
}
|
|
144
|
+
if (oldHash !== h) {
|
|
145
|
+
if (verbose)
|
|
146
|
+
console.log(` 🔄 File changed, preparing to push...`);
|
|
147
|
+
// Create complete skill object with updated prompt_script
|
|
148
|
+
const skillObject = {
|
|
149
|
+
id: skillMeta.id,
|
|
150
|
+
title: skillMeta.title,
|
|
151
|
+
idn: skillMeta.idn,
|
|
152
|
+
prompt_script: content,
|
|
153
|
+
runner_type: skillMeta.runner_type,
|
|
154
|
+
model: skillMeta.model,
|
|
155
|
+
parameters: skillMeta.parameters,
|
|
156
|
+
path: skillMeta.path || undefined
|
|
157
|
+
};
|
|
158
|
+
if (verbose) {
|
|
159
|
+
console.log(` 📤 Pushing skill object:`);
|
|
160
|
+
console.log(` ID: ${skillObject.id}`);
|
|
161
|
+
console.log(` Title: ${skillObject.title}`);
|
|
162
|
+
console.log(` IDN: ${skillObject.idn}`);
|
|
163
|
+
console.log(` Content length: ${content.length} chars`);
|
|
164
|
+
console.log(` Content preview: ${content.substring(0, 100).replace(/\n/g, '\\n')}...`);
|
|
165
|
+
}
|
|
166
|
+
await updateSkill(client, skillObject);
|
|
167
|
+
console.log(`↑ Pushed ${p}`);
|
|
168
|
+
newHashes[p] = h;
|
|
169
|
+
pushed++;
|
|
170
|
+
}
|
|
171
|
+
else if (verbose) {
|
|
172
|
+
console.log(` ✓ No changes`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (verbose)
|
|
179
|
+
console.log(`🔄 Scanned ${scanned} files, found ${pushed} changes`);
|
|
180
|
+
await saveHashes(newHashes);
|
|
181
|
+
console.log(pushed ? `✅ Push complete. ${pushed} file(s) updated.` : '✅ Nothing to push.');
|
|
182
|
+
}
|
|
183
|
+
export async function status(verbose = false) {
|
|
184
|
+
await ensureState();
|
|
185
|
+
if (!(await fs.pathExists(MAP_PATH))) {
|
|
186
|
+
console.log('No map. Run `newo pull` first.');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (verbose)
|
|
190
|
+
console.log('📋 Loading project mapping and hashes...');
|
|
191
|
+
const idMap = await fs.readJson(MAP_PATH);
|
|
192
|
+
const hashes = await loadHashes();
|
|
193
|
+
let dirty = 0;
|
|
194
|
+
// Handle both old single-project format and new multi-project format
|
|
195
|
+
const projects = 'projects' in idMap && idMap.projects ? idMap.projects : { '': idMap };
|
|
196
|
+
for (const [projectIdn, projectData] of Object.entries(projects)) {
|
|
197
|
+
if (verbose && projectIdn)
|
|
198
|
+
console.log(`📁 Checking project: ${projectIdn}`);
|
|
199
|
+
for (const [agentIdn, agentObj] of Object.entries(projectData.agents)) {
|
|
200
|
+
if (verbose)
|
|
201
|
+
console.log(` 📁 Checking agent: ${agentIdn}`);
|
|
202
|
+
for (const [flowIdn, flowObj] of Object.entries(agentObj.flows)) {
|
|
203
|
+
if (verbose)
|
|
204
|
+
console.log(` 📁 Checking flow: ${flowIdn}`);
|
|
205
|
+
for (const [skillIdn, skillMeta] of Object.entries(flowObj.skills)) {
|
|
206
|
+
const p = projectIdn ?
|
|
207
|
+
skillPath(projectIdn, agentIdn, flowIdn, skillIdn, skillMeta.runner_type) :
|
|
208
|
+
skillPath('', agentIdn, flowIdn, skillIdn, skillMeta.runner_type);
|
|
209
|
+
const exists = await fs.pathExists(p);
|
|
210
|
+
if (!exists) {
|
|
211
|
+
console.log(`D ${p}`);
|
|
212
|
+
dirty++;
|
|
213
|
+
if (verbose)
|
|
214
|
+
console.log(` ❌ Deleted: ${p}`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const content = await fs.readFile(p, 'utf8');
|
|
218
|
+
const h = sha256(content);
|
|
219
|
+
const oldHash = hashes[p];
|
|
220
|
+
if (verbose) {
|
|
221
|
+
console.log(` 📄 ${p}`);
|
|
222
|
+
console.log(` Old hash: ${oldHash || 'none'}`);
|
|
223
|
+
console.log(` New hash: ${h}`);
|
|
224
|
+
}
|
|
225
|
+
if (oldHash !== h) {
|
|
226
|
+
console.log(`M ${p}`);
|
|
227
|
+
dirty++;
|
|
228
|
+
if (verbose)
|
|
229
|
+
console.log(` 🔄 Modified: ${p}`);
|
|
230
|
+
}
|
|
231
|
+
else if (verbose) {
|
|
232
|
+
console.log(` ✓ Unchanged: ${p}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
console.log(dirty ? `${dirty} changed file(s).` : 'Clean.');
|
|
239
|
+
}
|
|
240
|
+
async function generateFlowsYaml(client, agents, projectIdn, verbose = false) {
|
|
241
|
+
const flowsData = { flows: [] };
|
|
242
|
+
for (const agent of agents) {
|
|
243
|
+
if (verbose)
|
|
244
|
+
console.log(` 📁 Processing agent: ${agent.idn}`);
|
|
245
|
+
const agentFlows = [];
|
|
246
|
+
for (const flow of agent.flows ?? []) {
|
|
247
|
+
if (verbose)
|
|
248
|
+
console.log(` 📄 Processing flow: ${flow.idn}`);
|
|
249
|
+
// Get skills for this flow
|
|
250
|
+
const skills = await listFlowSkills(client, flow.id);
|
|
251
|
+
const skillsData = skills.map(skill => ({
|
|
252
|
+
idn: skill.idn,
|
|
253
|
+
title: skill.title || "",
|
|
254
|
+
prompt_script: `flows/${flow.idn}/${skill.idn}.${skill.runner_type === 'nsl' ? 'jinja' : 'nsl'}`,
|
|
255
|
+
runner_type: `!enum "RunnerType.${skill.runner_type}"`,
|
|
256
|
+
model: {
|
|
257
|
+
model_idn: skill.model.model_idn,
|
|
258
|
+
provider_idn: skill.model.provider_idn
|
|
259
|
+
},
|
|
260
|
+
parameters: skill.parameters.map(param => ({
|
|
261
|
+
name: param.name,
|
|
262
|
+
default_value: param.default_value || " "
|
|
263
|
+
}))
|
|
264
|
+
}));
|
|
265
|
+
// Get events for this flow
|
|
266
|
+
let eventsData = [];
|
|
267
|
+
try {
|
|
268
|
+
const events = await listFlowEvents(client, flow.id);
|
|
269
|
+
eventsData = events.map(event => ({
|
|
270
|
+
title: event.description,
|
|
271
|
+
idn: event.idn,
|
|
272
|
+
skill_selector: `!enum "SkillSelector.${event.skill_selector}"`,
|
|
273
|
+
skill_idn: event.skill_idn || undefined,
|
|
274
|
+
state_idn: event.state_idn || undefined,
|
|
275
|
+
integration_idn: event.integration_idn || undefined,
|
|
276
|
+
connector_idn: event.connector_idn || undefined,
|
|
277
|
+
interrupt_mode: `!enum "InterruptMode.${event.interrupt_mode}"`
|
|
278
|
+
}));
|
|
279
|
+
if (verbose)
|
|
280
|
+
console.log(` 📋 Found ${events.length} events`);
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
if (verbose)
|
|
284
|
+
console.log(` ⚠️ No events found for flow ${flow.idn}`);
|
|
285
|
+
}
|
|
286
|
+
// Get state fields for this flow
|
|
287
|
+
let stateFieldsData = [];
|
|
288
|
+
try {
|
|
289
|
+
const states = await listFlowStates(client, flow.id);
|
|
290
|
+
stateFieldsData = states.map(state => ({
|
|
291
|
+
title: state.title,
|
|
292
|
+
idn: state.idn,
|
|
293
|
+
default_value: state.default_value || undefined,
|
|
294
|
+
scope: `!enum "StateFieldScope.${state.scope}"`
|
|
295
|
+
}));
|
|
296
|
+
if (verbose)
|
|
297
|
+
console.log(` 📊 Found ${states.length} state fields`);
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
if (verbose)
|
|
301
|
+
console.log(` ⚠️ No state fields found for flow ${flow.idn}`);
|
|
302
|
+
}
|
|
303
|
+
agentFlows.push({
|
|
304
|
+
idn: flow.idn,
|
|
305
|
+
title: flow.title,
|
|
306
|
+
description: flow.description || null,
|
|
307
|
+
default_runner_type: `!enum "RunnerType.${flow.default_runner_type}"`,
|
|
308
|
+
default_provider_idn: flow.default_model.provider_idn,
|
|
309
|
+
default_model_idn: flow.default_model.model_idn,
|
|
310
|
+
skills: skillsData,
|
|
311
|
+
events: eventsData,
|
|
312
|
+
state_fields: stateFieldsData
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
const agentData = {
|
|
316
|
+
agent_idn: agent.idn,
|
|
317
|
+
agent_description: agent.description || undefined,
|
|
318
|
+
agent_flows: agentFlows
|
|
319
|
+
};
|
|
320
|
+
flowsData.flows.push(agentData);
|
|
321
|
+
}
|
|
322
|
+
// Convert to YAML and write to file with custom enum handling
|
|
323
|
+
let yamlContent = yaml.dump(flowsData, {
|
|
324
|
+
indent: 2,
|
|
325
|
+
lineWidth: -1,
|
|
326
|
+
noRefs: true,
|
|
327
|
+
sortKeys: false,
|
|
328
|
+
quotingType: '"',
|
|
329
|
+
forceQuotes: false
|
|
330
|
+
});
|
|
331
|
+
// Post-process to fix enum formatting
|
|
332
|
+
yamlContent = yamlContent.replace(/"(!enum "[^"]+")"/g, '$1');
|
|
333
|
+
const yamlPath = path.join(projectDir(projectIdn), 'flows.yaml');
|
|
334
|
+
await writeFileAtomic(yamlPath, yamlContent);
|
|
335
|
+
console.log(`✓ Generated flows.yaml for ${projectIdn}`);
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=sync.js.map
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive type definitions for NEWO CLI
|
|
3
|
+
*/
|
|
4
|
+
export interface NewoEnvironment {
|
|
5
|
+
NEWO_BASE_URL?: string;
|
|
6
|
+
NEWO_PROJECT_ID?: string;
|
|
7
|
+
NEWO_API_KEY?: string;
|
|
8
|
+
NEWO_ACCESS_TOKEN?: string;
|
|
9
|
+
NEWO_REFRESH_TOKEN?: string;
|
|
10
|
+
NEWO_REFRESH_URL?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TokenResponse {
|
|
13
|
+
access_token?: string;
|
|
14
|
+
token?: string;
|
|
15
|
+
accessToken?: string;
|
|
16
|
+
refresh_token?: string;
|
|
17
|
+
refreshToken?: string;
|
|
18
|
+
expires_in?: number;
|
|
19
|
+
expiresIn?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface StoredTokens {
|
|
22
|
+
access_token: string;
|
|
23
|
+
refresh_token: string;
|
|
24
|
+
expires_at: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ProjectMeta {
|
|
27
|
+
id: string;
|
|
28
|
+
idn: string;
|
|
29
|
+
title: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
created_at?: string;
|
|
32
|
+
updated_at?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface Agent {
|
|
35
|
+
id: string;
|
|
36
|
+
idn: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
flows?: Flow[];
|
|
40
|
+
}
|
|
41
|
+
export interface Flow {
|
|
42
|
+
id: string;
|
|
43
|
+
idn: string;
|
|
44
|
+
title: string;
|
|
45
|
+
description?: string;
|
|
46
|
+
default_runner_type: RunnerType;
|
|
47
|
+
default_model: ModelConfig;
|
|
48
|
+
}
|
|
49
|
+
export interface ModelConfig {
|
|
50
|
+
model_idn: string;
|
|
51
|
+
provider_idn: string;
|
|
52
|
+
}
|
|
53
|
+
export interface SkillParameter {
|
|
54
|
+
name: string;
|
|
55
|
+
default_value?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface Skill {
|
|
58
|
+
id: string;
|
|
59
|
+
idn: string;
|
|
60
|
+
title: string;
|
|
61
|
+
prompt_script?: string;
|
|
62
|
+
runner_type: RunnerType;
|
|
63
|
+
model: ModelConfig;
|
|
64
|
+
parameters: SkillParameter[];
|
|
65
|
+
path?: string | undefined;
|
|
66
|
+
}
|
|
67
|
+
export interface FlowEvent {
|
|
68
|
+
id: string;
|
|
69
|
+
idn: string;
|
|
70
|
+
description: string;
|
|
71
|
+
skill_selector: SkillSelector;
|
|
72
|
+
skill_idn?: string;
|
|
73
|
+
state_idn?: string;
|
|
74
|
+
integration_idn?: string;
|
|
75
|
+
connector_idn?: string;
|
|
76
|
+
interrupt_mode: InterruptMode;
|
|
77
|
+
}
|
|
78
|
+
export interface FlowState {
|
|
79
|
+
id: string;
|
|
80
|
+
idn: string;
|
|
81
|
+
title: string;
|
|
82
|
+
default_value?: string;
|
|
83
|
+
scope: StateFieldScope;
|
|
84
|
+
}
|
|
85
|
+
export type RunnerType = 'guidance' | 'nsl';
|
|
86
|
+
export type SkillSelector = 'first' | 'last' | 'random' | 'all';
|
|
87
|
+
export type InterruptMode = 'allow' | 'deny' | 'queue';
|
|
88
|
+
export type StateFieldScope = 'flow' | 'agent' | 'project' | 'global';
|
|
89
|
+
export interface SkillMetadata {
|
|
90
|
+
id: string;
|
|
91
|
+
title: string;
|
|
92
|
+
idn: string;
|
|
93
|
+
runner_type: RunnerType;
|
|
94
|
+
model: ModelConfig;
|
|
95
|
+
parameters: SkillParameter[];
|
|
96
|
+
path?: string | undefined;
|
|
97
|
+
}
|
|
98
|
+
export interface FlowData {
|
|
99
|
+
id: string;
|
|
100
|
+
skills: Record<string, SkillMetadata>;
|
|
101
|
+
}
|
|
102
|
+
export interface AgentData {
|
|
103
|
+
id: string;
|
|
104
|
+
flows: Record<string, FlowData>;
|
|
105
|
+
}
|
|
106
|
+
export interface ProjectData {
|
|
107
|
+
projectId: string;
|
|
108
|
+
projectIdn: string;
|
|
109
|
+
agents: Record<string, AgentData>;
|
|
110
|
+
}
|
|
111
|
+
export interface ProjectMap {
|
|
112
|
+
projects: Record<string, ProjectData>;
|
|
113
|
+
}
|
|
114
|
+
export interface LegacyProjectMap extends ProjectData {
|
|
115
|
+
projects?: Record<string, ProjectData>;
|
|
116
|
+
}
|
|
117
|
+
export interface HashStore {
|
|
118
|
+
[filePath: string]: string;
|
|
119
|
+
}
|
|
120
|
+
export interface ParsedArticle {
|
|
121
|
+
topic_name: string;
|
|
122
|
+
persona_id: string | null;
|
|
123
|
+
topic_summary: string;
|
|
124
|
+
topic_facts: string[];
|
|
125
|
+
confidence: number;
|
|
126
|
+
source: string;
|
|
127
|
+
labels: string[];
|
|
128
|
+
}
|
|
129
|
+
export interface AkbImportArticle extends Omit<ParsedArticle, 'persona_id'> {
|
|
130
|
+
persona_id: string;
|
|
131
|
+
}
|
|
132
|
+
export interface CliArgs {
|
|
133
|
+
_: string[];
|
|
134
|
+
verbose?: boolean;
|
|
135
|
+
v?: boolean;
|
|
136
|
+
[key: string]: unknown;
|
|
137
|
+
}
|
|
138
|
+
export interface FlowsYamlSkill {
|
|
139
|
+
idn: string;
|
|
140
|
+
title: string;
|
|
141
|
+
prompt_script: string;
|
|
142
|
+
runner_type: string;
|
|
143
|
+
model: ModelConfig;
|
|
144
|
+
parameters: Array<{
|
|
145
|
+
name: string;
|
|
146
|
+
default_value: string;
|
|
147
|
+
}>;
|
|
148
|
+
}
|
|
149
|
+
export interface FlowsYamlEvent {
|
|
150
|
+
title: string;
|
|
151
|
+
idn: string;
|
|
152
|
+
skill_selector: string;
|
|
153
|
+
skill_idn?: string | undefined;
|
|
154
|
+
state_idn?: string | undefined;
|
|
155
|
+
integration_idn?: string | undefined;
|
|
156
|
+
connector_idn?: string | undefined;
|
|
157
|
+
interrupt_mode: string;
|
|
158
|
+
}
|
|
159
|
+
export interface FlowsYamlState {
|
|
160
|
+
title: string;
|
|
161
|
+
idn: string;
|
|
162
|
+
default_value?: string | undefined;
|
|
163
|
+
scope: string;
|
|
164
|
+
}
|
|
165
|
+
export interface FlowsYamlFlow {
|
|
166
|
+
idn: string;
|
|
167
|
+
title: string;
|
|
168
|
+
description: string | null;
|
|
169
|
+
default_runner_type: string;
|
|
170
|
+
default_provider_idn: string;
|
|
171
|
+
default_model_idn: string;
|
|
172
|
+
skills: FlowsYamlSkill[];
|
|
173
|
+
events: FlowsYamlEvent[];
|
|
174
|
+
state_fields: FlowsYamlState[];
|
|
175
|
+
}
|
|
176
|
+
export interface FlowsYamlAgent {
|
|
177
|
+
agent_idn: string;
|
|
178
|
+
agent_description?: string | undefined;
|
|
179
|
+
agent_flows: FlowsYamlFlow[];
|
|
180
|
+
}
|
|
181
|
+
export interface FlowsYamlData {
|
|
182
|
+
flows: FlowsYamlAgent[];
|
|
183
|
+
}
|
|
184
|
+
export interface AxiosClientConfig {
|
|
185
|
+
baseURL?: string;
|
|
186
|
+
headers?: Record<string, string>;
|
|
187
|
+
}
|
|
188
|
+
export interface NewoApiError extends Error {
|
|
189
|
+
response?: {
|
|
190
|
+
status: number;
|
|
191
|
+
data: unknown;
|
|
192
|
+
};
|
|
193
|
+
config?: {
|
|
194
|
+
method?: string;
|
|
195
|
+
url?: string;
|
|
196
|
+
headers?: Record<string, string>;
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
export type FileStatus = 'M' | 'D' | 'clean';
|
|
200
|
+
export interface StatusResult {
|
|
201
|
+
filePath: string;
|
|
202
|
+
status: FileStatus;
|
|
203
|
+
oldHash?: string;
|
|
204
|
+
newHash?: string;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "NEWO CLI: sync flows/skills between NEWO and local files, multi-project support, import AKB articles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"newo": "
|
|
7
|
+
"newo": "dist/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"
|
|
10
|
+
"dist/**/*.js",
|
|
11
|
+
"dist/**/*.d.ts",
|
|
12
|
+
"src/**/*.ts",
|
|
11
13
|
"README.md",
|
|
12
14
|
"CHANGELOG.md",
|
|
13
15
|
".env.example"
|
|
@@ -47,16 +49,28 @@
|
|
|
47
49
|
"minimist": "^1.2.8"
|
|
48
50
|
},
|
|
49
51
|
"devDependencies": {
|
|
50
|
-
"
|
|
52
|
+
"@types/fs-extra": "^11.0.4",
|
|
53
|
+
"@types/js-yaml": "^4.0.9",
|
|
54
|
+
"@types/minimist": "^1.2.5",
|
|
55
|
+
"@types/node": "^22.5.4",
|
|
56
|
+
"mocha": "^10.2.0",
|
|
57
|
+
"typescript": "^5.6.2"
|
|
51
58
|
},
|
|
52
59
|
"scripts": {
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
60
|
+
"build": "tsc",
|
|
61
|
+
"build:watch": "tsc --watch",
|
|
62
|
+
"dev": "npm run build && node ./dist/cli.js",
|
|
63
|
+
"dev:watch": "tsc --watch & nodemon --watch dist dist/cli.js",
|
|
64
|
+
"pull": "npm run build && node ./dist/cli.js pull",
|
|
65
|
+
"push": "npm run build && node ./dist/cli.js push",
|
|
66
|
+
"status": "npm run build && node ./dist/cli.js status",
|
|
67
|
+
"clean": "rm -rf dist",
|
|
68
|
+
"typecheck": "tsc --noEmit",
|
|
69
|
+
"lint": "tsc --noEmit --strict",
|
|
70
|
+
"test": "npm run build && mocha test/*.test.js --timeout 60000",
|
|
71
|
+
"test:api": "npm run build && mocha test/api.test.js --timeout 30000",
|
|
72
|
+
"test:sync": "npm run build && mocha test/sync.test.js --timeout 60000",
|
|
73
|
+
"test:integration": "npm run build && mocha test/integration.test.js --timeout 120000",
|
|
74
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
61
75
|
}
|
|
62
76
|
}
|