@igoruehara/canvas-flow 0.1.0 → 0.1.2
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/README.md
CHANGED
|
@@ -12,22 +12,22 @@ Canvas Flow roda frontend e backend juntos a partir de um pacote npm.
|
|
|
12
12
|
Este caminho sobe MongoDB local automaticamente e abre o navegador.
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npx canvas-flow@latest --with-docker --open
|
|
15
|
+
npx @igoruehara/canvas-flow@latest --with-docker --open
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Para RAG local com Milvus, MinIO e etcd:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
npx canvas-flow@latest infra up --full
|
|
22
|
-
npx canvas-flow@latest --open
|
|
21
|
+
npx @igoruehara/canvas-flow@latest infra up --full
|
|
22
|
+
npx @igoruehara/canvas-flow@latest --open
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Comandos uteis:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
npx canvas-flow@latest infra status
|
|
29
|
-
npx canvas-flow@latest infra logs
|
|
30
|
-
npx canvas-flow@latest infra down
|
|
28
|
+
npx @igoruehara/canvas-flow@latest infra status
|
|
29
|
+
npx @igoruehara/canvas-flow@latest infra logs
|
|
30
|
+
npx @igoruehara/canvas-flow@latest infra down
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
`infra down` para os containers, mas mantem os volumes Docker.
|
|
@@ -37,7 +37,7 @@ npx canvas-flow@latest infra down
|
|
|
37
37
|
Use este caminho quando voce ja tem MongoDB local, Atlas ou outro Mongo remoto.
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
npx canvas-flow@latest --open
|
|
40
|
+
npx @igoruehara/canvas-flow@latest --open
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Mongo local padrao:
|
|
@@ -49,7 +49,7 @@ mongodb://127.0.0.1:27017/canvas_flow
|
|
|
49
49
|
Para usar outro Mongo, edite a config:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
npx canvas-flow@latest config --edit
|
|
52
|
+
npx @igoruehara/canvas-flow@latest config --edit
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
```json
|
|
@@ -77,13 +77,13 @@ C:\Users\<usuario>\.canvas-flow\config.json
|
|
|
77
77
|
Abrir a config:
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
npx canvas-flow@latest config --edit
|
|
80
|
+
npx @igoruehara/canvas-flow@latest config --edit
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
Ver o caminho da config:
|
|
84
84
|
|
|
85
85
|
```bash
|
|
86
|
-
npx canvas-flow@latest config
|
|
86
|
+
npx @igoruehara/canvas-flow@latest config
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
Exemplo com OpenAI:
|
|
@@ -112,7 +112,7 @@ Exemplo com porta customizada:
|
|
|
112
112
|
Tambem da para usar outro arquivo:
|
|
113
113
|
|
|
114
114
|
```bash
|
|
115
|
-
npx canvas-flow@latest --config C:\canvas-flow\config.json --open
|
|
115
|
+
npx @igoruehara/canvas-flow@latest --config C:\canvas-flow\config.json --open
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
Nao publique `config.json`: ele contem tokens e secrets gerados.
|
|
@@ -120,13 +120,13 @@ Nao publique `config.json`: ele contem tokens e secrets gerados.
|
|
|
120
120
|
## Validar
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
npx canvas-flow@latest doctor
|
|
123
|
+
npx @igoruehara/canvas-flow@latest doctor
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
Sem checar rede/Mongo:
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
|
-
npx canvas-flow@latest doctor --offline
|
|
129
|
+
npx @igoruehara/canvas-flow@latest doctor --offline
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
## Instalar globalmente
|
|
@@ -134,7 +134,7 @@ npx canvas-flow@latest doctor --offline
|
|
|
134
134
|
Opcional:
|
|
135
135
|
|
|
136
136
|
```bash
|
|
137
|
-
npm i -g canvas-flow
|
|
137
|
+
npm i -g @igoruehara/canvas-flow
|
|
138
138
|
canvas-flow --with-docker --open
|
|
139
139
|
```
|
|
140
140
|
|
package/bin/canvas-flow.js
CHANGED
|
@@ -50,6 +50,7 @@ Options:
|
|
|
50
50
|
--edit Open config file with "init" or "config"
|
|
51
51
|
--force Overwrite config on init
|
|
52
52
|
--offline Skip network checks with "doctor"
|
|
53
|
+
--skip-mongo-check Start without preflight MongoDB connection check
|
|
53
54
|
--strict Treat doctor warnings as failures
|
|
54
55
|
--help Show this help
|
|
55
56
|
|
|
@@ -810,6 +811,48 @@ async function checkMongoReachability(uri) {
|
|
|
810
811
|
};
|
|
811
812
|
}
|
|
812
813
|
|
|
814
|
+
function sleep(ms) {
|
|
815
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
function mongoConnectionOptions(config) {
|
|
819
|
+
return {
|
|
820
|
+
serverSelectionTimeoutMS: Number(config.database?.mongoServerSelectionTimeoutMs || 8000),
|
|
821
|
+
connectTimeoutMS: Number(config.database?.mongoConnectTimeoutMs || 8000),
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
async function checkMongoConnection(uri, options = {}) {
|
|
826
|
+
let connection;
|
|
827
|
+
try {
|
|
828
|
+
const mongoose = require('mongoose');
|
|
829
|
+
connection = mongoose.createConnection(uri, options);
|
|
830
|
+
await connection.asPromise();
|
|
831
|
+
return { ok: true, message: 'connected' };
|
|
832
|
+
} catch (error) {
|
|
833
|
+
return { ok: false, message: error && error.message ? error.message : String(error) };
|
|
834
|
+
} finally {
|
|
835
|
+
if (connection) {
|
|
836
|
+
await connection.close().catch(() => undefined);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function isLocalMongoUri(uri) {
|
|
842
|
+
return mongoTargetsFromUri(uri).some((target) => (
|
|
843
|
+
target.host === '127.0.0.1' ||
|
|
844
|
+
target.host === 'localhost' ||
|
|
845
|
+
target.host === '::1'
|
|
846
|
+
));
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
function mongoConnectionHint(uri) {
|
|
850
|
+
if (isLocalMongoUri(uri)) {
|
|
851
|
+
return 'Start local Mongo with "canvas-flow infra up", or run with "canvas-flow --with-docker --open".';
|
|
852
|
+
}
|
|
853
|
+
return 'Check database.mongoUrl credentials, network access, and the MongoDB Atlas IP access list.';
|
|
854
|
+
}
|
|
855
|
+
|
|
813
856
|
function dockerComposeBaseArgs() {
|
|
814
857
|
return [
|
|
815
858
|
'compose',
|
|
@@ -936,6 +979,7 @@ function createDoctorReporter(strict) {
|
|
|
936
979
|
|
|
937
980
|
async function doctor(flags) {
|
|
938
981
|
const reporter = createDoctorReporter(flags.strict === true);
|
|
982
|
+
addSourceDependencyFallback();
|
|
939
983
|
const paths = resolvePaths(flags);
|
|
940
984
|
ensureDir(paths.homeDir);
|
|
941
985
|
|
|
@@ -975,11 +1019,11 @@ async function doctor(flags) {
|
|
|
975
1019
|
if (config.database.mongoUrl) {
|
|
976
1020
|
reporter.pass('Mongo config', 'MONGO_DB_CONNECTION_STRING is set');
|
|
977
1021
|
if (flags.offline === true) {
|
|
978
|
-
reporter.warn('Mongo
|
|
1022
|
+
reporter.warn('Mongo connection', 'skipped because --offline was used');
|
|
979
1023
|
} else {
|
|
980
|
-
const mongoCheck = await
|
|
981
|
-
if (mongoCheck.ok) reporter.pass('Mongo
|
|
982
|
-
else reporter.fail('Mongo
|
|
1024
|
+
const mongoCheck = await checkMongoConnection(config.database.mongoUrl, mongoConnectionOptions(config));
|
|
1025
|
+
if (mongoCheck.ok) reporter.pass('Mongo connection', mongoCheck.message);
|
|
1026
|
+
else reporter.fail('Mongo connection', `${mongoCheck.message}; ${mongoConnectionHint(config.database.mongoUrl)}`);
|
|
983
1027
|
}
|
|
984
1028
|
} else {
|
|
985
1029
|
reporter.fail('Mongo config', 'database.mongoUrl is required');
|
|
@@ -1044,7 +1088,41 @@ async function doctor(flags) {
|
|
|
1044
1088
|
reporter.finish();
|
|
1045
1089
|
}
|
|
1046
1090
|
|
|
1047
|
-
function
|
|
1091
|
+
async function waitForMongo(config, flags, paths) {
|
|
1092
|
+
if (flags['skip-mongo-check'] === true) return;
|
|
1093
|
+
if (!config.database.mongoUrl) {
|
|
1094
|
+
throw new Error(`database.mongoUrl is required. Edit the config with: canvas-flow config --edit`);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
const attempts = (flags['with-docker'] === true || flags.infra === true) && isLocalMongoUri(config.database.mongoUrl)
|
|
1098
|
+
? 20
|
|
1099
|
+
: 1;
|
|
1100
|
+
const options = mongoConnectionOptions(config);
|
|
1101
|
+
let lastMessage = '';
|
|
1102
|
+
|
|
1103
|
+
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
1104
|
+
const result = await checkMongoConnection(config.database.mongoUrl, options);
|
|
1105
|
+
if (result.ok) {
|
|
1106
|
+
console.log('MongoDB preflight: connected');
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
lastMessage = result.message;
|
|
1111
|
+
if (attempt < attempts) {
|
|
1112
|
+
console.log(`MongoDB preflight waiting (${attempt}/${attempts}): ${result.message}`);
|
|
1113
|
+
await sleep(1500);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
throw new Error([
|
|
1118
|
+
`MongoDB preflight failed: ${lastMessage}`,
|
|
1119
|
+
mongoConnectionHint(config.database.mongoUrl),
|
|
1120
|
+
`Config file: ${paths.configPath}`,
|
|
1121
|
+
'Use "canvas-flow doctor" for a detailed readiness check.',
|
|
1122
|
+
].join('\n'));
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
async function start(flags) {
|
|
1048
1126
|
assertBundleExists();
|
|
1049
1127
|
addSourceDependencyFallback();
|
|
1050
1128
|
if (flags['with-docker'] === true || flags.infra === true) {
|
|
@@ -1055,6 +1133,7 @@ function start(flags) {
|
|
|
1055
1133
|
const configExisted = fs.existsSync(paths.configPath);
|
|
1056
1134
|
const config = loadConfig(paths.configPath);
|
|
1057
1135
|
const runtime = applyEnvironment(config, paths, flags);
|
|
1136
|
+
await waitForMongo(config, flags, paths);
|
|
1058
1137
|
|
|
1059
1138
|
process.chdir(paths.homeDir);
|
|
1060
1139
|
|
|
@@ -1117,7 +1196,7 @@ async function main() {
|
|
|
1117
1196
|
}
|
|
1118
1197
|
|
|
1119
1198
|
if (args.command === 'start' || args.command === 'run') {
|
|
1120
|
-
start(args.flags);
|
|
1199
|
+
await start(args.flags);
|
|
1121
1200
|
return;
|
|
1122
1201
|
}
|
|
1123
1202
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
"version": "0.1.
|
|
2
|
+
"name": "@igoruehara/canvas-flow",
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Standalone npm launcher for Canvas Flow multi-agent GenAI workflows.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -65,4 +65,4 @@
|
|
|
65
65
|
"overrides": {
|
|
66
66
|
"uuid": "^11.1.1"
|
|
67
67
|
}
|
|
68
|
-
}
|
|
68
|
+
}
|
|
@@ -12,13 +12,17 @@ exports.databaseProviders = [
|
|
|
12
12
|
const uri = configService.get('MONGO_DB_CONNECTION_STRING') ||
|
|
13
13
|
'mongodb://127.0.0.1:27017/canvas_flow';
|
|
14
14
|
mongoose.set('bufferCommands', false);
|
|
15
|
-
|
|
16
|
-
.connect(uri, {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
try {
|
|
16
|
+
await mongoose.connect(uri, {
|
|
17
|
+
serverSelectionTimeoutMS: Number(configService.get('MONGO_SERVER_SELECTION_TIMEOUT_MS') || 8000),
|
|
18
|
+
connectTimeoutMS: Number(configService.get('MONGO_CONNECT_TIMEOUT_MS') || 8000),
|
|
19
|
+
});
|
|
20
|
+
console.log('MongoDB connected');
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(`MongoDB connection failed: ${error?.message || String(error)}`);
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
22
26
|
return mongoose;
|
|
23
27
|
},
|
|
24
28
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.providers.js","sourceRoot":"","sources":["../../src/database/database.providers.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AACrC,2CAA+C;AAC/C,4DAAuE;AAE1D,QAAA,iBAAiB,GAAG;IAC/B;QACE,OAAO,EAAE,iDAA8B;QACvC,MAAM,EAAE,CAAC,sBAAa,CAAC;QACvB,UAAU,EAAE,KAAK,EAAE,aAA4B,EAA4B,EAAE;YAC3E,MAAM,GAAG,GACP,aAAa,CAAC,GAAG,CAAS,4BAA4B,CAAC;gBACvD,uCAAuC,CAAC;YAC1C,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;YACtC,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"database.providers.js","sourceRoot":"","sources":["../../src/database/database.providers.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AACrC,2CAA+C;AAC/C,4DAAuE;AAE1D,QAAA,iBAAiB,GAAG;IAC/B;QACE,OAAO,EAAE,iDAA8B;QACvC,MAAM,EAAE,CAAC,sBAAa,CAAC;QACvB,UAAU,EAAE,KAAK,EAAE,aAA4B,EAA4B,EAAE;YAC3E,MAAM,GAAG,GACP,aAAa,CAAC,GAAG,CAAS,4BAA4B,CAAC;gBACvD,uCAAuC,CAAC;YAC1C,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE;oBAC1B,wBAAwB,EAAE,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,mCAAmC,CAAC,IAAI,IAAI,CAAC;oBAChG,gBAAgB,EAAE,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,0BAA0B,CAAC,IAAI,IAAI,CAAC;iBAChF,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC/E,MAAM,KAAK,CAAC;YACd,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF;CACF,CAAC"}
|