@javierfrancoleal/docfactory 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +27 -2
- package/assets/docfactory.md +68 -0
- package/assets/docfx.py +174 -0
- package/cordis.patch.yml +4 -0
- package/icon.svg +8 -0
- package/lib/index.js +45 -0
- package/locale/ar.json +6 -0
- package/locale/de.json +6 -0
- package/locale/en.json +6 -0
- package/locale/es.json +6 -0
- package/locale/fr.json +6 -0
- package/locale/it.json +6 -0
- package/locale/ja.json +6 -0
- package/locale/ko.json +6 -0
- package/locale/pt.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +17 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 J.Franco
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "The professional document factory: consulting-grade techniques + editorial DNA + the reusable docfx.py library."
|
|
3
|
+
kind: "package-bundle"
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# @javierfrancoleal/docfactory
|
|
7
|
+
|
|
8
|
+
Created by **J.Franco**.
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
When the model creates professional documents (business plans, one-pagers,
|
|
13
|
+
agreements), this skill applies consulting-grade techniques — boxes that
|
|
14
|
+
never split across pages (cantSplit + keep-next chains), repeating table
|
|
15
|
+
headers, no orphan/widow lines, page numbers, document metadata,
|
|
16
|
+
consistent hyperlinks — plus the Franco Vision editorial DNA (no
|
|
17
|
+
meta-pointers, narrative flow, modest numbers, no over-promising, one
|
|
18
|
+
concept defined once).
|
|
19
|
+
|
|
20
|
+
## Use
|
|
21
|
+
|
|
22
|
+
Ask "docfactory" before creating or polishing any Word/PDF document.
|
|
23
|
+
The skill points to the reusable `docfx.py` library (in the plugin
|
|
24
|
+
assets) that implements every technique.
|
|
25
|
+
|
|
26
|
+
## License
|
|
27
|
+
|
|
28
|
+
MIT — see the package license field.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Docfactory — the professional document factory
|
|
2
|
+
|
|
3
|
+
Use this skill whenever a professional document is created or polished
|
|
4
|
+
(Word/PDF: business plans, one-pagers, agreements, guides). Two pillars:
|
|
5
|
+
the consulting techniques and the editorial DNA. Both were validated on
|
|
6
|
+
real documents and are implemented in a reusable library.
|
|
7
|
+
|
|
8
|
+
## Pillar 1 — The consulting techniques (layout)
|
|
9
|
+
|
|
10
|
+
1. **Boxes never straddle pages** — two mechanisms together:
|
|
11
|
+
`cantSplit` on every table row (a row never breaks) AND a keep-next
|
|
12
|
+
chain across rows (every row sticks to the next), so the WHOLE box
|
|
13
|
+
moves together or not at all.
|
|
14
|
+
2. **Table headers repeat** — `tblHeader` on the first row: if a table
|
|
15
|
+
continues on another page, its header reappears.
|
|
16
|
+
3. **No orphan/widow lines** — `widowControl` on the Normal style and
|
|
17
|
+
every paragraph.
|
|
18
|
+
4. **Headings stick to their content** — keep-with-next on section
|
|
19
|
+
labels and titles.
|
|
20
|
+
5. **Page numbers** — a real PAGE field in the footer.
|
|
21
|
+
6. **Document metadata** — core properties (title, author, subject,
|
|
22
|
+
company) so the file identifies itself in any operating system.
|
|
23
|
+
7. **Hyperlinks** — blue, underlined, external relationships, one per
|
|
24
|
+
claim.
|
|
25
|
+
8. **Delegable reading guides** — every section names its reader
|
|
26
|
+
("À lire par : ...").
|
|
27
|
+
9. **One design language** — Arial, a single accent color, gray
|
|
28
|
+
hairlines, generous line spacing (1.18).
|
|
29
|
+
10. **Balanced emphasis** — bold only for the essential.
|
|
30
|
+
|
|
31
|
+
## Pillar 2 — The editorial DNA (writing)
|
|
32
|
+
|
|
33
|
+
- **No meta-pointers**: never "voir la section X", never "(the sources
|
|
34
|
+
are in section 2)". If a link proves it, the link proves it.
|
|
35
|
+
- **Narrative flow**: the text reads like a story; nothing is deferred
|
|
36
|
+
to another part.
|
|
37
|
+
- **Modest numbers**: verify every figure against a public source or
|
|
38
|
+
mark it "en suspens, à valider". No exaggerated projections.
|
|
39
|
+
- **No over-promising**: never "sans risques" — promise what is real
|
|
40
|
+
(control, accountability, accompaniment).
|
|
41
|
+
- **One concept defined once**: no repetitions; if a point must
|
|
42
|
+
resurface, it resurfaces in its exact place, not everywhere.
|
|
43
|
+
- **Human accountability**: the AI prepares; the human decides, signs
|
|
44
|
+
and assumes — and this is a selling point, not a limitation.
|
|
45
|
+
|
|
46
|
+
## The library
|
|
47
|
+
|
|
48
|
+
The plugin assets contain `docfx.py` — a python-docx library that
|
|
49
|
+
implements Pillar 1 (new_doc, header_block, rule, section, para, bullet,
|
|
50
|
+
cite, table3, footer). To use it: copy `docfx.py` into the workspace,
|
|
51
|
+
then in the generator:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import sys; sys.path.insert(0, ".")
|
|
55
|
+
from docfx import *
|
|
56
|
+
doc = new_doc(title, subject)
|
|
57
|
+
table3(doc, rows, widths, header=("A", "B", "C"))
|
|
58
|
+
footer(doc, "Company line", "Document id · Date")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Checklist before delivering
|
|
62
|
+
|
|
63
|
+
1. Every table row has cantSplit + the keep-next chain.
|
|
64
|
+
2. No section header is orphaned at a page bottom.
|
|
65
|
+
3. Page numbers and metadata present.
|
|
66
|
+
4. No "voir la section", no "sans risques", no repeated concepts.
|
|
67
|
+
5. Accents survive copy-paste (explicit font: Arial, fr-CA language).
|
|
68
|
+
6. Every claim links to a verifiable public source.
|
package/assets/docfx.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# docfx — the Franco Vision document factory.
|
|
2
|
+
# Professional consulting techniques, one reusable library:
|
|
3
|
+
# · cantSplit + keepNext chains (boxes never straddle pages)
|
|
4
|
+
# · tblHeader (table headers repeat when a table continues)
|
|
5
|
+
# · widowControl (no orphan lines at page breaks)
|
|
6
|
+
# · page numbers (PAGE field) + document core properties
|
|
7
|
+
# · hyperlinks, hairline rules, delegable section headers
|
|
8
|
+
# · consistent palette (blue #4D6BFE, grays, Arial, fr-CA)
|
|
9
|
+
import sys
|
|
10
|
+
from docx import Document
|
|
11
|
+
from docx.shared import Pt, Cm, RGBColor
|
|
12
|
+
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
13
|
+
from docx.enum.table import WD_TABLE_ALIGNMENT
|
|
14
|
+
from docx.oxml.ns import qn
|
|
15
|
+
from docx.oxml import OxmlElement
|
|
16
|
+
from docx.opc.constants import RELATIONSHIP_TYPE
|
|
17
|
+
|
|
18
|
+
INK = RGBColor(0x11, 0x18, 0x27)
|
|
19
|
+
MUTED = RGBColor(0x6B, 0x72, 0x80)
|
|
20
|
+
FAINT = RGBColor(0x9C, 0xA3, 0xAF)
|
|
21
|
+
V = RGBColor(0x4D, 0x6B, 0xFE)
|
|
22
|
+
GRAY = RGBColor(0x4B, 0x55, 0x63)
|
|
23
|
+
LOCKUP = "tools/logo-suite/franco-vision-lockup.png"
|
|
24
|
+
FONT = "Arial"
|
|
25
|
+
|
|
26
|
+
def new_doc(title, subject, margins=(1.4, 1.2, 1.6, 1.6)):
|
|
27
|
+
"""Document with the house style: Arial, fr-CA, margins, core properties."""
|
|
28
|
+
doc = Document()
|
|
29
|
+
s = doc.sections[0]
|
|
30
|
+
s.top_margin, s.bottom_margin, s.left_margin, s.right_margin = (Cm(x) for x in margins)
|
|
31
|
+
st = doc.styles["Normal"]
|
|
32
|
+
st.font.name = FONT
|
|
33
|
+
st.font.size = Pt(9.5)
|
|
34
|
+
rPr = st.element.get_or_add_rPr()
|
|
35
|
+
rFonts = rPr.find(qn("w:rFonts"))
|
|
36
|
+
if rFonts is None:
|
|
37
|
+
rFonts = OxmlElement("w:rFonts"); rPr.append(rFonts)
|
|
38
|
+
for attr in ("ascii", "hAnsi", "cs"):
|
|
39
|
+
rFonts.set(qn("w:" + attr), FONT)
|
|
40
|
+
lang = OxmlElement("w:lang"); lang.set(qn("w:val"), "fr-CA"); rPr.append(lang)
|
|
41
|
+
wc = OxmlElement("w:widowControl"); rPr.append(wc) # no orphan lines
|
|
42
|
+
cp = doc.core_properties
|
|
43
|
+
cp.title = title
|
|
44
|
+
cp.author = "Javier Alejandro FRANCO LEAL"
|
|
45
|
+
cp.subject = subject
|
|
46
|
+
cp.company = "Franco Vision inc."
|
|
47
|
+
return doc
|
|
48
|
+
|
|
49
|
+
def add_hyperlink(paragraph, text, url, size=9):
|
|
50
|
+
part = paragraph.part
|
|
51
|
+
r_id = part.relate_to(url, RELATIONSHIP_TYPE.HYPERLINK, is_external=True)
|
|
52
|
+
hl = OxmlElement("w:hyperlink"); hl.set(qn("r:id"), r_id)
|
|
53
|
+
run = OxmlElement("w:r"); rPr = OxmlElement("w:rPr")
|
|
54
|
+
c = OxmlElement("w:color"); c.set(qn("w:val"), "4D6BFE"); rPr.append(c)
|
|
55
|
+
u = OxmlElement("w:u"); u.set(qn("w:val"), "single"); rPr.append(u)
|
|
56
|
+
sz = OxmlElement("w:sz"); sz.set(qn("w:val"), str(int(size * 2))); rPr.append(sz)
|
|
57
|
+
run.append(rPr)
|
|
58
|
+
t_el = OxmlElement("w:t"); t_el.text = text; run.append(t_el)
|
|
59
|
+
hl.append(run); paragraph._p.append(hl)
|
|
60
|
+
|
|
61
|
+
def rule(doc, color="4D6BFE", sz=6, space_after=8):
|
|
62
|
+
p = doc.add_paragraph(); pPr = p._p.get_or_add_pPr(); pBdr = OxmlElement("w:pBdr")
|
|
63
|
+
b = OxmlElement("w:bottom")
|
|
64
|
+
b.set(qn("w:val"), "single"); b.set(qn("w:sz"), str(sz)); b.set(qn("w:color"), color); b.set(qn("w:space"), "4")
|
|
65
|
+
pBdr.append(b); pPr.append(pBdr)
|
|
66
|
+
p.paragraph_format.space_after = Pt(space_after)
|
|
67
|
+
return p
|
|
68
|
+
|
|
69
|
+
def para(doc, text="", size=9.5, color=INK, bold=False, align=None, space_after=4, space_before=0, line=1.18, keep_next=False):
|
|
70
|
+
p = doc.add_paragraph(); r = p.add_run(text)
|
|
71
|
+
r.font.size = Pt(size); r.font.color.rgb = color; r.bold = bold
|
|
72
|
+
if align is not None: p.alignment = align
|
|
73
|
+
pf = p.paragraph_format
|
|
74
|
+
pf.space_after = Pt(space_after); pf.space_before = Pt(space_before); pf.line_spacing = line
|
|
75
|
+
pf.keep_with_next = keep_next
|
|
76
|
+
pPr = p._p.get_or_add_pPr()
|
|
77
|
+
if pPr.find(qn("w:widowControl")) is None:
|
|
78
|
+
pPr.append(OxmlElement("w:widowControl"))
|
|
79
|
+
return p
|
|
80
|
+
|
|
81
|
+
def section(doc, num, title, audience, size=14):
|
|
82
|
+
para(doc, "SECTION " + num, size=8, color=V, bold=True, space_before=12, space_after=1, keep_next=True)
|
|
83
|
+
para(doc, title, size=size, bold=True, space_after=2, keep_next=True)
|
|
84
|
+
p = doc.add_paragraph()
|
|
85
|
+
r = p.add_run("À lire par : " + audience)
|
|
86
|
+
r.font.size = Pt(8.5); r.font.color.rgb = GRAY; r.italic = True
|
|
87
|
+
p.paragraph_format.space_after = Pt(4)
|
|
88
|
+
rule(doc, color="E5E7EB", sz=4, space_after=6)
|
|
89
|
+
|
|
90
|
+
def bullet(doc, lead, rest, size=9.5):
|
|
91
|
+
p = doc.add_paragraph()
|
|
92
|
+
r1 = p.add_run("· " + lead); r1.bold = True; r1.font.size = Pt(size); r1.font.color.rgb = INK
|
|
93
|
+
r2 = p.add_run(rest); r2.font.size = Pt(size); r2.font.color.rgb = MUTED
|
|
94
|
+
p.paragraph_format.space_after = Pt(3)
|
|
95
|
+
p.paragraph_format.line_spacing = 1.18
|
|
96
|
+
return p
|
|
97
|
+
|
|
98
|
+
def cite(doc, text, url, size=9):
|
|
99
|
+
p = doc.add_paragraph(); add_hyperlink(p, text, url, size=size)
|
|
100
|
+
p.paragraph_format.space_after = Pt(2)
|
|
101
|
+
return p
|
|
102
|
+
|
|
103
|
+
def shade(cell, hexcolor):
|
|
104
|
+
tcPr = cell._tc.get_or_add_tcPr()
|
|
105
|
+
shd = OxmlElement("w:shd"); shd.set(qn("w:val"), "clear"); shd.set(qn("w:fill"), hexcolor)
|
|
106
|
+
tcPr.append(shd)
|
|
107
|
+
|
|
108
|
+
def cell_borders(cell, edges, color="E5E7EB", sz=4):
|
|
109
|
+
tcPr = cell._tc.get_or_add_tcPr(); b = OxmlElement("w:tcBorders")
|
|
110
|
+
for side in edges:
|
|
111
|
+
el = OxmlElement("w:" + side)
|
|
112
|
+
el.set(qn("w:val"), "single"); el.set(qn("w:sz"), str(sz)); el.set(qn("w:color"), color)
|
|
113
|
+
b.append(el)
|
|
114
|
+
tcPr.append(b)
|
|
115
|
+
|
|
116
|
+
def no_split(row):
|
|
117
|
+
trPr = row._tr.get_or_add_trPr()
|
|
118
|
+
if trPr.find(qn("w:cantSplit")) is None:
|
|
119
|
+
trPr.append(OxmlElement("w:cantSplit"))
|
|
120
|
+
|
|
121
|
+
def keep_together(t):
|
|
122
|
+
"""Chain every row to the next: the whole box moves together, never straddles pages."""
|
|
123
|
+
for r in t.rows[:-1]:
|
|
124
|
+
for c in r.cells:
|
|
125
|
+
for p in c.paragraphs:
|
|
126
|
+
p.paragraph_format.keep_with_next = True
|
|
127
|
+
|
|
128
|
+
def header_repeats(t):
|
|
129
|
+
"""The header row repeats when the table continues on the next page."""
|
|
130
|
+
trPr = t.rows[0]._tr.get_or_add_trPr()
|
|
131
|
+
if trPr.find(qn("w:tblHeader")) is None:
|
|
132
|
+
trPr.append(OxmlElement("w:tblHeader"))
|
|
133
|
+
|
|
134
|
+
def table3(doc, rows, widths=(2.2, 10.0, 5.0), header=("", "", "")):
|
|
135
|
+
t = doc.add_table(rows=1, cols=3); t.autofit = False
|
|
136
|
+
no_split(t.rows[0])
|
|
137
|
+
for i, htxt in enumerate(header):
|
|
138
|
+
c = t.rows[0].cells[i]; c.width = Cm(widths[i]); shade(c, "F3F4F6")
|
|
139
|
+
p = c.paragraphs[0]; r = p.add_run(htxt); r.bold = True; r.font.size = Pt(8.5); r.font.color.rgb = MUTED
|
|
140
|
+
p.paragraph_format.space_before = Pt(2); p.paragraph_format.space_after = Pt(2)
|
|
141
|
+
for a, b, c3 in rows:
|
|
142
|
+
rw = t.add_row(); no_split(rw)
|
|
143
|
+
for i, val in enumerate((a, b, c3)):
|
|
144
|
+
c = rw.cells[i]; c.width = Cm(widths[i]); cell_borders(c, ["bottom"])
|
|
145
|
+
p = c.paragraphs[0]; r = p.add_run(val); r.font.size = Pt(9)
|
|
146
|
+
p.paragraph_format.space_before = Pt(2); p.paragraph_format.space_after = Pt(2)
|
|
147
|
+
if i == 0: r.bold = True; r.font.color.rgb = V
|
|
148
|
+
elif i == 2: r.bold = True; r.font.color.rgb = INK
|
|
149
|
+
else: r.font.color.rgb = INK
|
|
150
|
+
keep_together(t); header_repeats(t)
|
|
151
|
+
return t
|
|
152
|
+
|
|
153
|
+
def header_block(doc, doctype, lockup_width=4.2):
|
|
154
|
+
t = doc.add_table(rows=1, cols=2); t.alignment = WD_TABLE_ALIGNMENT.CENTER; t.autofit = False
|
|
155
|
+
t.columns[0].width = Cm(11.0); t.columns[1].width = Cm(6.8)
|
|
156
|
+
c0, c1 = t.rows[0].cells
|
|
157
|
+
p0 = c0.paragraphs[0]; p0.add_run().add_picture(LOCKUP, width=Cm(lockup_width))
|
|
158
|
+
p1 = c1.paragraphs[0]; p1.alignment = WD_ALIGN_PARAGRAPH.RIGHT
|
|
159
|
+
r4 = p1.add_run(doctype); r4.font.size = Pt(8); r4.bold = True; r4.font.color.rgb = MUTED
|
|
160
|
+
return t
|
|
161
|
+
|
|
162
|
+
def footer(doc, text, docid):
|
|
163
|
+
rule(doc, color="E5E7EB", sz=4, space_after=4)
|
|
164
|
+
p = doc.add_paragraph(); p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
165
|
+
r = p.add_run(text + " · Page ")
|
|
166
|
+
r.font.size = Pt(7.5); r.font.color.rgb = FAINT
|
|
167
|
+
fld = OxmlElement("w:fldSimple"); fld.set(qn("w:instr"), "PAGE")
|
|
168
|
+
rr = OxmlElement("w:r"); tt = OxmlElement("w:t"); tt.text = "1"; rr.append(tt); fld.append(rr)
|
|
169
|
+
p._p.append(fld)
|
|
170
|
+
p.paragraph_format.space_after = Pt(1)
|
|
171
|
+
p2 = doc.add_paragraph(); p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
172
|
+
r2 = p2.add_run(docid)
|
|
173
|
+
r2.font.size = Pt(7); r2.font.color.rgb = FAINT
|
|
174
|
+
p2.paragraph_format.space_after = Pt(0)
|
package/cordis.patch.yml
ADDED
package/icon.svg
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
|
2
|
+
<rect width="64" height="64" rx="14" fill="#4D6BFE"/>
|
|
3
|
+
<rect x="16" y="10" width="32" height="44" rx="3" fill="#ffffff"/>
|
|
4
|
+
<line x1="22" y1="20" x2="42" y2="20" stroke="#4D6BFE" stroke-width="2.5" stroke-linecap="round"/>
|
|
5
|
+
<line x1="22" y1="28" x2="42" y2="28" stroke="#4D6BFE" stroke-width="2.5" stroke-linecap="round"/>
|
|
6
|
+
<line x1="22" y1="36" x2="34" y2="36" stroke="#9CA3AF" stroke-width="2.5" stroke-linecap="round"/>
|
|
7
|
+
<circle cx="46" cy="46" r="6" fill="#FACC15"/>
|
|
8
|
+
</svg>
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @javierfrancoleal/docfactory — an organ of the J.Franco agentic workflow.
|
|
2
|
+
// Created by J.Franco. Registers the docfactory skill provider.
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { BUNDLED_SKILL_RANK } from "@deepseek-ai/dsh-skill";
|
|
6
|
+
|
|
7
|
+
const PROVIDER_NAME = "javierfrancoleal-docfactory";
|
|
8
|
+
const SKILL_BODY_URL = new URL("../assets/docfactory.md", import.meta.url);
|
|
9
|
+
const RESOURCE_BASE = { kind: "directory", path: fileURLToPath(new URL("../assets/", import.meta.url)) };
|
|
10
|
+
|
|
11
|
+
const CANDIDATE = {
|
|
12
|
+
name: "docfactory",
|
|
13
|
+
description: "The professional document factory of the J.Franco agentic workflow: consulting-grade layout techniques (boxes that never split pages, repeating table headers, no orphan lines, page numbers, metadata) + the editorial DNA (no meta-pointers, narrative flow, modest numbers, no over-promising) + the reusable docfx.py library.",
|
|
14
|
+
invocation: { modelInvocable: true, userInvocable: true },
|
|
15
|
+
provider: PROVIDER_NAME,
|
|
16
|
+
source: "bundled",
|
|
17
|
+
resourceBase: RESOURCE_BASE,
|
|
18
|
+
rank: BUNDLED_SKILL_RANK,
|
|
19
|
+
locator: SKILL_BODY_URL,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const provider = {
|
|
23
|
+
name: PROVIDER_NAME,
|
|
24
|
+
list: () => Promise.resolve([CANDIDATE]),
|
|
25
|
+
async get() {
|
|
26
|
+
return {
|
|
27
|
+
name: CANDIDATE.name,
|
|
28
|
+
description: CANDIDATE.description,
|
|
29
|
+
invocation: CANDIDATE.invocation,
|
|
30
|
+
provider: CANDIDATE.provider,
|
|
31
|
+
source: CANDIDATE.source,
|
|
32
|
+
resourceBase: RESOURCE_BASE,
|
|
33
|
+
content: await readFile(SKILL_BODY_URL, "utf8"),
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const name = "docfactory";
|
|
39
|
+
const inject = ["skills"];
|
|
40
|
+
|
|
41
|
+
function apply(ctx) {
|
|
42
|
+
ctx.skills.registerProvider(() => provider);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { apply, inject, name };
|
package/locale/ar.json
ADDED
package/locale/de.json
ADDED
package/locale/en.json
ADDED
package/locale/es.json
ADDED
package/locale/fr.json
ADDED
package/locale/it.json
ADDED
package/locale/ja.json
ADDED
package/locale/ko.json
ADDED
package/locale/pt.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@javierfrancoleal/docfactory",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "The professional document factory of the J.Franco agentic workflow: consulting-grade techniques (boxes that never split pages, repeating table headers, no orphan lines, page numbers, metadata) + the editorial DNA (no meta-pointers, narrative flow, modest numbers, no over-promising) + a reusable docfx.py library. Created by J.Franco.",
|
|
5
|
+
"author": "J.Franco",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "lib/index.js",
|
|
9
|
+
"exports": { ".": "./lib/index.js", "./cordis.patch.yml": "./cordis.patch.yml", "./package.json": "./package.json", "./locale/*.json": "./locale/*.json" },
|
|
10
|
+
"icon": "./icon.svg",
|
|
11
|
+
"files": ["icon.svg", "locale/*.json", "lib/index.js", "assets", "cordis.patch.yml", "README.md"],
|
|
12
|
+
"engines": { "node": ">=24", "dsh": ">=0.2.1-rc.0" },
|
|
13
|
+
"repository": { "type": "git", "url": "git+https://github.com/JavierFrancoLeal/jfranco-agentic-suite.git", "directory": "jfranco-docfactory" },
|
|
14
|
+
"homepage": "https://github.com/JavierFrancoLeal/jfranco-agentic-suite",
|
|
15
|
+
"keywords": ["deepseek-harness", "agentic-workflow", "super-agent", "documents", "docx", "consulting"],
|
|
16
|
+
"dsh": { "manifestVersion": 1, "bundle": { "patch": "./cordis.patch.yml" } },
|
|
17
|
+
"publishConfig": { "access": "public" },
|
|
18
|
+
"peerDependencies": { "@deepseek-ai/cordis": "~4.0.5", "@deepseek-ai/dsh-skill": ">=0.2.1-rc.5" }
|
|
19
|
+
}
|