diff --git a/src/66/66-parser.c b/src/66/66-parser.c
deleted file mode 100644
index 344ed9b584fae55d17ca4614191398af1b8a49aa..0000000000000000000000000000000000000000
--- a/src/66/66-parser.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 66-parser.c
- *
- * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
- *
- * All rights reserved.
- *
- * This file is part of Obarun. It is subject to the license terms in
- * the LICENSE file found in the top-level directory of this
- * distribution.
- * This file may not be copied, modified, propagated, or distributed
- * except according to the terms contained in the LICENSE file./
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdint.h>
-
-#include <oblibs/log.h>
-#include <oblibs/files.h>
-#include <oblibs/obgetopt.h>
-#include <oblibs/types.h>
-#include <oblibs/directory.h>
-#include <oblibs/string.h>
-#include <oblibs/sastr.h>
-
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
-
-#include <66/utils.h>
-#include <66/parser.h>
-#include <66/constants.h>
-
-#define USAGE "66-parser [ -h ] [ -z ] [ -v verbosity ] [ -f ] [ -I ] service destination"
-
-static inline void info_help (void)
-{
-    DEFAULT_MSG = 0 ;
-
-    static char const *help =
-"\n"
-"options :\n"
-"   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -f: force to overwrite existing destination\n"
-"   -I: do not import modified configuration files from previous version\n"
-;
-
-    log_info(USAGE,"\n",help) ;
-}
-
-static void check_dir(char const *dir,uint8_t force,int main)
-{
-    log_flow() ;
-
-    int r ;
-
-    r = scan_mode(dir,S_IFDIR) ;
-    if (r < 0){ errno = ENOTDIR ; log_diesys(LOG_EXIT_SYS,"conflicting format of: ",dir) ; }
-
-    if (r && force && main)
-    {
-        if ((rm_rf(dir) < 0) || !r ) log_dieusys(LOG_EXIT_SYS,"sanitize directory: ",dir) ;
-        r = 0 ;
-    }
-    else if (r && !force && main) log_die(LOG_EXIT_SYS,"destination: ",dir," already exist") ;
-    if (!r)
-        if (!dir_create_parent(dir, 0755)) log_dieusys(LOG_EXIT_SYS,"create: ",dir) ;
-}
-
-int main(int argc, char const *const *argv,char const *const *envp)
-{
-    int ista ;
-    stralloc src = STRALLOC_ZERO ;
-    stralloc dst = STRALLOC_ZERO ;
-    stralloc insta = STRALLOC_ZERO ;
-    sv_alltype service = SV_ALLTYPE_ZERO ;
-    size_t srcdirlen, namelen ;
-    char const *dir ;
-    char const *sv  ;
-    char name[4095+1] ;
-    char srcdir[4095+1] ;
-    unsigned int type ;
-    uint8_t force = 0 , conf = 0 ;
-
-    log_color = &log_color_disable ;
-
-    PROG = "66-parser" ;
-    {
-        subgetopt l = SUBGETOPT_ZERO ;
-
-        for (;;)
-        {
-            int opt = getopt_args(argc,argv, ">hv:fcCzI", &l) ;
-            if (opt == -1) break ;
-            if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
-            switch (opt)
-            {
-                case 'h' :  info_help(); return 0 ;
-                case 'v' :  if (!uint0_scan(l.arg, &VERBOSITY)) log_usage(USAGE) ; break ;
-                case 'f' :  force = 1 ; break ;
-                case 'c' :  log_1_warn("deprecated option -- ignoring") ; break ;
-                case 'm' :  log_1_warn("deprecated option -- ignoring") ; break ;
-                case 'C' :  log_1_warn("deprecated option -- ignoring") ; break ;
-                case 'I' :  conf = 1 ; break ;
-                case 'z' :  log_color = !isatty(1) ? &log_color_disable : &log_color_enable ; break ;
-                default :   log_usage(USAGE) ;
-            }
-        }
-        argc -= l.ind ; argv += l.ind ;
-    }
-
-    if (argc < 2) log_usage(USAGE) ;
-
-    sv = argv[0] ;
-    dir = argv[1] ;
-
-    if (dir[0] != '/') log_die(LOG_EXIT_USER, "directory: ",dir," must be an absolute path") ;
-    if (sv[0] != '/') log_die(LOG_EXIT_USER, "service: ",sv," must be an absolute path") ;
-
-    if (!ob_basename(name,sv)) log_dieu(LOG_EXIT_SYS,"set name");
-
-    namelen = strlen(name) ;
-
-    if (!ob_dirname(srcdir,sv)) log_dieu(LOG_EXIT_SYS,"set directory name") ;
-
-    check_dir(dir,force,0) ;
-
-    if (!auto_stra(&insta,name)) log_die_nomem("stralloc") ;
-
-    ista = instance_check(insta.s) ;
-    if (!ista) log_die(LOG_EXIT_SYS,"invalid instance name: ",insta.s) ;
-
-    if (ista > 0)
-    {
-        if (!instance_splitname(&insta,name,ista,SS_INSTANCE_TEMPLATE)) log_dieu(LOG_EXIT_SYS,"split instance name of: ",name) ;
-    }
-
-    log_trace("read service file of: ",srcdir,insta.s) ;
-    if (read_svfile(&src,insta.s,srcdir) <= 0) log_dieusys(LOG_EXIT_SYS,"open: ",sv) ;
-
-    if (!get_svtype(&service,src.s)) log_dieu(LOG_EXIT_SYS,"get service type of: ",sv) ;
-
-    if (ista > 0)
-    {
-        if (!instance_create(&src,name,SS_INSTANCE_REGEX,ista))
-            log_dieu(LOG_EXIT_SYS,"create instance service: ",name) ;
-    }
-
-    service.cname.name = keep.len ;
-    if (!stralloc_catb(&keep,name,namelen + 1)) log_die_nomem("stralloc") ;
-
-    if (!parser(&service,&src,sv,service.cname.itype)) log_dieu(LOG_EXIT_SYS,"parse service file: ",sv) ;
-
-    if (!auto_stra(&dst,dir,"/",name)) log_die_nomem("stralloc") ;
-
-    check_dir(dst.s,force,1) ;
-
-    type = service.cname.itype ;
-    srcdirlen = strlen(srcdir) ;
-    service.src = keep.len ;
-
-    if (!stralloc_catb(&keep,srcdir,srcdirlen + 1)) log_die_nomem("stralloc") ;
-
-    /* save and prepare environment file */
-    if (service.opts[2])
-    {
-
-        stralloc conf = STRALLOC_ZERO ;
-        if (!stralloc_catb(&conf,dst.s,dst.len) ||
-        !stralloc_cats(&conf,"/env") ||
-        !stralloc_0(&conf)) log_die_nomem("stralloc") ;
-        if (!scan_mode(conf.s,S_IFDIR))
-        {
-            if (!dir_create_parent(conf.s,0755)) log_dieusys(LOG_EXIT_SYS,"environment directory: ",conf.s) ;
-        }
-        service.srconf = keep.len ;
-        if (!stralloc_catb(&keep,conf.s,conf.len + 1)) log_die_nomem("stralloc") ;
-        stralloc_free(&conf) ;
-    }
-
-    switch(type)
-    {
-        case TYPE_CLASSIC:
-            if (!write_classic(&service, dst.s, force, conf))
-                log_dieu(LOG_EXIT_SYS,"write: ",name) ;
-            break ;
-        case TYPE_LONGRUN:
-            if (!write_longrun(&service, dst.s, force, conf))
-                log_dieu(LOG_EXIT_SYS,"write: ",name) ;
-            break ;
-        case TYPE_ONESHOT:
-            if (!write_oneshot(&service, dst.s, conf))
-                log_dieu(LOG_EXIT_SYS,"write: ",name) ;
-            break ;
-        case TYPE_MODULE:
-            if (!write_common(&service,dst.s, conf))
-                log_warnu_return(LOG_EXIT_ZERO,"write common files") ;
-        case TYPE_BUNDLE:
-            if (!write_bundle(&service, dst.s))
-                log_dieu(LOG_EXIT_SYS,"write: ",name) ;
-            break ;
-        default: break ;
-    }
-
-    log_info("Written successfully: ",name, " at: ",dir) ;
-
-    sv_alltype_free(&service) ;
-    stralloc_free(&keep) ;
-    stralloc_free(&deps) ;
-    stralloc_free(&src) ;
-    stralloc_free(&dst) ;
-
-    return 0 ;
-}
diff --git a/src/66/deps-exe/66-parser b/src/66/deps-exe/66-parser
deleted file mode 100644
index 9c58365fcec451152a7b10b51a36af3a3612a3fa..0000000000000000000000000000000000000000
--- a/src/66/deps-exe/66-parser
+++ /dev/null
@@ -1,3 +0,0 @@
-${LIB66}
--loblibs
--lskarnet
diff --git a/src/lib66/exec/ssexec_parse.c b/src/lib66/exec/ssexec_parse.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e00ecb6ad61cfa7712f9390807f35e04ed97d09
--- /dev/null
+++ b/src/lib66/exec/ssexec_parse.c
@@ -0,0 +1,120 @@
+/*
+ * ssexec_parse.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <oblibs/string.h>
+#include <oblibs/log.h>
+#include <oblibs/types.h>
+#include <oblibs/directory.h>
+#include <oblibs/obgetopt.h>
+
+#include <66/parser.h>
+#include <66/ssexec.h>
+
+static void check_dir(char const *dir, uint8_t force, int main)
+{
+    log_flow() ;
+
+    int r ;
+
+    r = scan_mode(dir, S_IFDIR) ;
+    if (r < 0) {
+        errno = ENOTDIR ;
+        log_diesys(LOG_EXIT_SYS,"conflicting format of: ",dir) ;
+    }
+
+    if (r && force && main) {
+
+        if ((dir_rm_rf(dir) < 0) || !r )
+            log_dieusys(LOG_EXIT_SYS,"sanitize directory: ",dir) ;
+        r = 0 ;
+
+    } else if (r && !force && main)
+        log_die(LOG_EXIT_SYS,"destination: ",dir," already exist") ;
+
+    if (!r)
+        if (!dir_create_parent(dir, 0755))
+            log_dieusys(LOG_EXIT_SYS,"create: ",dir) ;
+}
+
+int ssexec_parse(int argc, char const *const *argv, ssexec_t *info)
+{
+    char const *dir ;
+    char const *sv  ;
+
+    uint8_t force = 0 , conf = 0 ;
+
+    {
+        subgetopt l = SUBGETOPT_ZERO ;
+
+        for (;;)
+        {
+            int opt = getopt_args(argc,argv, ">" OPTS_PARSE, &l) ;
+            if (opt == -1) break ;
+            if (opt == -2) log_die(LOG_EXIT_USER, "options must be set first") ;
+            switch (opt)
+            {
+                case 'f' :
+
+                    /** only rewrite the service itself */
+                    force = 1 ;
+                    break ;
+
+                case 'F' :
+
+                    /** force to rewrite it dependencies */
+                    force = 2 ;
+                    break ;
+
+                case 'I' :
+
+                    conf = 1 ;
+                    break ;
+
+                case 'c' :  log_1_warn("deprecated option -- ignoring") ; break ;
+                case 'm' :  log_1_warn("deprecated option -- ignoring") ; break ;
+                case 'C' :  log_1_warn("deprecated option -- ignoring") ; break ;
+
+                default :
+                    log_usage(usage_parse) ;
+            }
+        }
+        argc -= l.ind ; argv += l.ind ;
+    }
+
+    if (argc < 2) log_usage(usage_parse) ;
+
+    sv = argv[0] ;
+    dir = argv[1] ;
+
+    if (dir[0] != '/')
+        log_die(LOG_EXIT_USER, "directory: ",dir," must be an absolute path") ;
+
+    if (sv[0] != '/')
+        log_die(LOG_EXIT_USER, "service: ",sv," must be an absolute path") ;
+
+    char name[strlen(sv)] ;
+
+    if (!ob_basename(name, sv))
+        log_dieusys(LOG_EXIT_SYS, "get basename of: ", sv) ;
+
+    parser(sv, dir, info, force, 0) ;
+
+    log_info("Written successfully: ",name, " at: ",dir) ;
+
+    return 0 ;
+}