@open-agreements/open-agreements 0.2.0 → 0.2.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 +10 -2
- package/content/templates/closing-checklist/metadata.yaml +6 -13
- package/content/templates/closing-checklist/template.docx +0 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +47 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/checklist.d.ts +21 -1
- package/dist/commands/checklist.d.ts.map +1 -1
- package/dist/commands/checklist.js +175 -44
- package/dist/commands/checklist.js.map +1 -1
- package/dist/commands/recipe.js +3 -11
- package/dist/commands/recipe.js.map +1 -1
- package/dist/core/checklist/index.d.ts +22 -14
- package/dist/core/checklist/index.d.ts.map +1 -1
- package/dist/core/checklist/index.js +79 -39
- package/dist/core/checklist/index.js.map +1 -1
- package/dist/core/checklist/jsonl-stores.d.ts +3 -0
- package/dist/core/checklist/jsonl-stores.d.ts.map +1 -0
- package/dist/core/checklist/jsonl-stores.js +16 -0
- package/dist/core/checklist/jsonl-stores.js.map +1 -0
- package/dist/core/checklist/schemas.d.ts +2 -2
- package/dist/core/checklist/schemas.js +1 -1
- package/dist/core/checklist/schemas.js.map +1 -1
- package/dist/core/checklist/state-manager.d.ts +146 -0
- package/dist/core/checklist/state-manager.d.ts.map +1 -0
- package/dist/core/checklist/state-manager.js +147 -0
- package/dist/core/checklist/state-manager.js.map +1 -0
- package/dist/core/checklist/status-labels.d.ts +6 -0
- package/dist/core/checklist/status-labels.d.ts.map +1 -0
- package/dist/core/checklist/status-labels.js +29 -0
- package/dist/core/checklist/status-labels.js.map +1 -0
- package/dist/core/validation/recipe.d.ts.map +1 -1
- package/dist/core/validation/recipe.js +47 -61
- package/dist/core/validation/recipe.js.map +1 -1
- package/package.json +1 -1
- package/skills/cloud-service-agreement/SKILL.md +9 -0
- package/skills/data-privacy-agreement/SKILL.md +9 -0
- package/skills/edit-docx-agreement/CONNECTORS.md +20 -0
- package/skills/edit-docx-agreement/SKILL.md +77 -0
- package/skills/employment-contract/SKILL.md +9 -0
- package/skills/iso-27001-evidence-collection/CONNECTORS.md +23 -0
- package/skills/iso-27001-evidence-collection/SKILL.md +300 -0
- package/skills/iso-27001-evidence-collection/rules/api-exports.md +191 -0
- package/skills/iso-27001-evidence-collection/rules/evidence-types.md +107 -0
- package/skills/iso-27001-evidence-collection/rules/screenshot-guide.md +77 -0
- package/skills/iso-27001-internal-audit/CONNECTORS.md +23 -0
- package/skills/iso-27001-internal-audit/SKILL.md +272 -0
- package/skills/iso-27001-internal-audit/rules/access-control.md +191 -0
- package/skills/iso-27001-internal-audit/rules/business-continuity.md +94 -0
- package/skills/iso-27001-internal-audit/rules/change-management.md +211 -0
- package/skills/iso-27001-internal-audit/rules/encryption.md +93 -0
- package/skills/iso-27001-internal-audit/rules/incident-response.md +127 -0
- package/skills/iso-27001-internal-audit/rules/isms-management.md +164 -0
- package/skills/iso-27001-internal-audit/rules/logging-monitoring.md +96 -0
- package/skills/iso-27001-internal-audit/rules/people-controls.md +161 -0
- package/skills/iso-27001-internal-audit/rules/supplier-management.md +92 -0
- package/skills/nda/SKILL.md +9 -0
- package/skills/open-agreements/SKILL.md +9 -0
- package/skills/safe/SKILL.md +9 -0
- package/skills/services-agreement/SKILL.md +9 -0
- package/skills/soc2-readiness/CONNECTORS.md +23 -0
- package/skills/soc2-readiness/SKILL.md +289 -0
- package/skills/soc2-readiness/rules/trust-services.md +230 -0
- package/skills/venture-financing/SKILL.md +9 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { appendJsonl, readJsonl } from './jsonl-stores.js';
|
|
7
|
+
import { ClosingChecklistSchema } from './schemas.js';
|
|
8
|
+
const STATE_ROOT = join(homedir(), '.open-agreements', 'checklists');
|
|
9
|
+
export const ChecklistStateSchema = z.object({
|
|
10
|
+
checklist_id: z.string().min(1),
|
|
11
|
+
revision: z.number().int().nonnegative(),
|
|
12
|
+
checklist: ClosingChecklistSchema,
|
|
13
|
+
});
|
|
14
|
+
function stateRoot(root) {
|
|
15
|
+
return root ?? STATE_ROOT;
|
|
16
|
+
}
|
|
17
|
+
function checklistDir(uuid, root) {
|
|
18
|
+
return join(stateRoot(root), uuid);
|
|
19
|
+
}
|
|
20
|
+
function statePath(uuid, root) {
|
|
21
|
+
return join(checklistDir(uuid, root), 'state.json');
|
|
22
|
+
}
|
|
23
|
+
function metaPath(uuid, root) {
|
|
24
|
+
return join(checklistDir(uuid, root), 'meta.json');
|
|
25
|
+
}
|
|
26
|
+
function historyPath(uuid, root) {
|
|
27
|
+
return join(checklistDir(uuid, root), 'history.jsonl');
|
|
28
|
+
}
|
|
29
|
+
function writeJson(path, value) {
|
|
30
|
+
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, 'utf-8');
|
|
31
|
+
}
|
|
32
|
+
function readJson(path) {
|
|
33
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
34
|
+
}
|
|
35
|
+
export function createChecklist(dealName, initialData, opts) {
|
|
36
|
+
const uuid = randomUUID();
|
|
37
|
+
const dir = checklistDir(uuid, opts?.root);
|
|
38
|
+
mkdirSync(dir, { recursive: true });
|
|
39
|
+
const now = new Date().toISOString().slice(0, 10);
|
|
40
|
+
const checklist = initialData ?? {
|
|
41
|
+
deal_name: dealName,
|
|
42
|
+
updated_at: now,
|
|
43
|
+
documents: {},
|
|
44
|
+
checklist_entries: {},
|
|
45
|
+
action_items: {},
|
|
46
|
+
issues: {},
|
|
47
|
+
};
|
|
48
|
+
const state = {
|
|
49
|
+
checklist_id: uuid,
|
|
50
|
+
revision: 0,
|
|
51
|
+
checklist,
|
|
52
|
+
};
|
|
53
|
+
const meta = {
|
|
54
|
+
deal_name: dealName,
|
|
55
|
+
created_at: now,
|
|
56
|
+
uuid,
|
|
57
|
+
};
|
|
58
|
+
writeJson(statePath(uuid, opts?.root), state);
|
|
59
|
+
writeJson(metaPath(uuid, opts?.root), meta);
|
|
60
|
+
return { uuid, dir };
|
|
61
|
+
}
|
|
62
|
+
export function listChecklists(opts) {
|
|
63
|
+
const root = stateRoot(opts?.root);
|
|
64
|
+
if (!existsSync(root))
|
|
65
|
+
return [];
|
|
66
|
+
const entries = readdirSync(root, { withFileTypes: true });
|
|
67
|
+
const results = [];
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
if (!entry.isDirectory())
|
|
70
|
+
continue;
|
|
71
|
+
const mp = metaPath(entry.name, opts?.root);
|
|
72
|
+
const sp = statePath(entry.name, opts?.root);
|
|
73
|
+
if (!existsSync(mp) || !existsSync(sp))
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
const meta = readJson(mp);
|
|
77
|
+
const state = readJson(sp);
|
|
78
|
+
results.push({
|
|
79
|
+
...meta,
|
|
80
|
+
revision: state.revision,
|
|
81
|
+
updated_at: state.checklist.updated_at,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Skip corrupt entries
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return results.sort((a, b) => a.deal_name.localeCompare(b.deal_name));
|
|
89
|
+
}
|
|
90
|
+
export function resolveChecklist(nameOrId, opts) {
|
|
91
|
+
const root = stateRoot(opts?.root);
|
|
92
|
+
if (!existsSync(root))
|
|
93
|
+
return null;
|
|
94
|
+
// Exact UUID match
|
|
95
|
+
const exactDir = checklistDir(nameOrId, opts?.root);
|
|
96
|
+
if (existsSync(join(exactDir, 'state.json')))
|
|
97
|
+
return nameOrId;
|
|
98
|
+
// Fuzzy match by deal name
|
|
99
|
+
const entries = readdirSync(root, { withFileTypes: true });
|
|
100
|
+
const needle = nameOrId.toLowerCase();
|
|
101
|
+
for (const entry of entries) {
|
|
102
|
+
if (!entry.isDirectory())
|
|
103
|
+
continue;
|
|
104
|
+
const mp = metaPath(entry.name, opts?.root);
|
|
105
|
+
if (!existsSync(mp))
|
|
106
|
+
continue;
|
|
107
|
+
try {
|
|
108
|
+
const meta = readJson(mp);
|
|
109
|
+
if (meta.deal_name.toLowerCase() === needle)
|
|
110
|
+
return entry.name;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Skip
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Substring match as fallback
|
|
117
|
+
for (const entry of entries) {
|
|
118
|
+
if (!entry.isDirectory())
|
|
119
|
+
continue;
|
|
120
|
+
const mp = metaPath(entry.name, opts?.root);
|
|
121
|
+
if (!existsSync(mp))
|
|
122
|
+
continue;
|
|
123
|
+
try {
|
|
124
|
+
const meta = readJson(mp);
|
|
125
|
+
if (meta.deal_name.toLowerCase().includes(needle))
|
|
126
|
+
return entry.name;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Skip
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
export function getChecklistState(uuid, opts) {
|
|
135
|
+
const path = statePath(uuid, opts?.root);
|
|
136
|
+
return ChecklistStateSchema.parse(readJson(path));
|
|
137
|
+
}
|
|
138
|
+
export function saveChecklistState(uuid, state, opts) {
|
|
139
|
+
writeJson(statePath(uuid, opts?.root), state);
|
|
140
|
+
}
|
|
141
|
+
export async function appendHistory(uuid, record, opts) {
|
|
142
|
+
await appendJsonl(historyPath(uuid, opts?.root), record);
|
|
143
|
+
}
|
|
144
|
+
export function getHistory(uuid, opts) {
|
|
145
|
+
return readJsonl(historyPath(uuid, opts?.root));
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=state-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-manager.js","sourceRoot":"","sources":["../../../src/core/checklist/state-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-labels.d.ts","sourceRoot":"","sources":["../../../src/core/checklist/status-labels.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAwBhD,CAAC;AAEF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable labels for checklist enum statuses.
|
|
3
|
+
*/
|
|
4
|
+
export const STATUS_LABELS = {
|
|
5
|
+
// ChecklistEntryStatusEnum
|
|
6
|
+
NOT_STARTED: 'Not Started',
|
|
7
|
+
DRAFT: 'Draft',
|
|
8
|
+
CIRCULATED: 'Circulated',
|
|
9
|
+
FORM_FINAL: 'Form Final',
|
|
10
|
+
PARTIALLY_SIGNED: 'Partially Signed',
|
|
11
|
+
FULLY_EXECUTED: 'Fully Executed',
|
|
12
|
+
DELIVERED: 'Delivered',
|
|
13
|
+
FILED_OR_RECORDED: 'Filed / Recorded',
|
|
14
|
+
// ChecklistItemStatusEnum (action items)
|
|
15
|
+
IN_PROGRESS: 'In Progress',
|
|
16
|
+
COMPLETED: 'Completed',
|
|
17
|
+
ON_HOLD: 'On Hold',
|
|
18
|
+
// SignatoryStatusEnum
|
|
19
|
+
PENDING: 'Pending',
|
|
20
|
+
RECEIVED: 'Received',
|
|
21
|
+
N_A: 'N/A',
|
|
22
|
+
// IssueStatusEnum
|
|
23
|
+
OPEN: 'Open',
|
|
24
|
+
CLOSED: 'Closed',
|
|
25
|
+
};
|
|
26
|
+
export function humanStatus(status) {
|
|
27
|
+
return STATUS_LABELS[status] ?? status;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=status-labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-labels.js","sourceRoot":"","sources":["../../../src/core/checklist/status-labels.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,2BAA2B;IAC3B,WAAW,EAAE,aAAa;IAC1B,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,gBAAgB,EAAE,kBAAkB;IACpC,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,WAAW;IACtB,iBAAiB,EAAE,kBAAkB;IAErC,yCAAyC;IACzC,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAElB,sBAAsB;IACtB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,GAAG,EAAE,KAAK;IAEV,kBAAkB;IAClB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;AACzC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipe.d.ts","sourceRoot":"","sources":["../../../src/core/validation/recipe.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AASD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,sBAAsB,
|
|
1
|
+
{"version":3,"file":"recipe.d.ts","sourceRoot":"","sources":["../../../src/core/validation/recipe.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AASD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,sBAAsB,CAwIxB"}
|
|
@@ -48,12 +48,8 @@ export function validateRecipe(recipeDir, recipeId, options) {
|
|
|
48
48
|
ComputedProfileSchema.parse(JSON.parse(raw));
|
|
49
49
|
}
|
|
50
50
|
catch (err) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
errors.push('computed.json: invalid format');
|
|
56
|
-
}
|
|
51
|
+
const message = err instanceof Error ? err.message : 'invalid format';
|
|
52
|
+
errors.push(`computed.json: ${message}`);
|
|
57
53
|
}
|
|
58
54
|
}
|
|
59
55
|
if (isScaffold) {
|
|
@@ -65,68 +61,58 @@ export function validateRecipe(recipeDir, recipeId, options) {
|
|
|
65
61
|
}
|
|
66
62
|
return { recipeId, valid: errors.length === 0, scaffold: true, errors, warnings };
|
|
67
63
|
}
|
|
68
|
-
// Validate replacements.json
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
unknownTargets.add(fieldName);
|
|
99
|
-
}
|
|
64
|
+
// Validate replacements.json for runnable recipes.
|
|
65
|
+
try {
|
|
66
|
+
const raw = readFileSync(join(recipeDir, 'replacements.json'), 'utf-8');
|
|
67
|
+
const replacements = JSON.parse(raw);
|
|
68
|
+
if (typeof replacements !== 'object' || replacements === null) {
|
|
69
|
+
errors.push('replacements.json must be a JSON object');
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const unknownTargets = new Set();
|
|
73
|
+
for (const [key, value] of Object.entries(replacements)) {
|
|
74
|
+
if (typeof value !== 'string') {
|
|
75
|
+
errors.push(`replacements.json: value for "${key}" must be a string`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Value must contain at least one {identifier} tag
|
|
79
|
+
const tags = value.match(TAG_RE);
|
|
80
|
+
if (!tags || tags.length === 0) {
|
|
81
|
+
errors.push(`replacements.json: value for "${key}" must contain at least one {identifier} tag, got "${value}"`);
|
|
82
|
+
}
|
|
83
|
+
// All curly-brace tokens in value must be safe identifiers (no control tags)
|
|
84
|
+
const allBraces = value.match(ANY_BRACE_RE);
|
|
85
|
+
if (allBraces) {
|
|
86
|
+
for (const token of allBraces) {
|
|
87
|
+
if (!SAFE_TAG_RE.test(token)) {
|
|
88
|
+
errors.push(`replacements.json: unsafe tag "${token}" in value for "${key}". Only {identifier} tags allowed.`);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const fieldName = token.slice(1, -1);
|
|
92
|
+
if (!metadataFieldNames.has(fieldName)) {
|
|
93
|
+
unknownTargets.add(fieldName);
|
|
100
94
|
}
|
|
101
95
|
}
|
|
102
|
-
// Value must not contain the source key (infinite loop prevention)
|
|
103
|
-
// For qualified keys, check against the searchText, not the full key.
|
|
104
|
-
// Nth keys use single-shot replacement so they can't loop — skip the check.
|
|
105
|
-
const parsed = parseReplacementKey(key, value);
|
|
106
|
-
if (parsed.type === 'simple' && value.includes(parsed.searchText)) {
|
|
107
|
-
errors.push(`replacements.json: value for "${key}" contains the key itself (would cause infinite loop)`);
|
|
108
|
-
}
|
|
109
|
-
else if (parsed.type === 'context' && value.includes(parsed.searchText)) {
|
|
110
|
-
errors.push(`replacements.json: value for "${key}" contains the search text "${parsed.searchText}" (would cause infinite loop)`);
|
|
111
|
-
}
|
|
112
|
-
// nth keys: no infinite-loop check needed (single-shot replacement)
|
|
113
96
|
}
|
|
114
|
-
|
|
115
|
-
|
|
97
|
+
// Value must not contain the source key (infinite loop prevention)
|
|
98
|
+
// For qualified keys, check against the searchText, not the full key.
|
|
99
|
+
// Nth keys use single-shot replacement so they can't loop — skip the check.
|
|
100
|
+
const parsed = parseReplacementKey(key, value);
|
|
101
|
+
if (parsed.type === 'simple' && value.includes(parsed.searchText)) {
|
|
102
|
+
errors.push(`replacements.json: value for "${key}" contains the key itself (would cause infinite loop)`);
|
|
103
|
+
}
|
|
104
|
+
else if (parsed.type === 'context' && value.includes(parsed.searchText)) {
|
|
105
|
+
errors.push(`replacements.json: value for "${key}" contains the search text "${parsed.searchText}" (would cause infinite loop)`);
|
|
116
106
|
}
|
|
107
|
+
// nth keys: no infinite-loop check needed (single-shot replacement)
|
|
108
|
+
}
|
|
109
|
+
for (const fieldName of unknownTargets) {
|
|
110
|
+
warnings.push(`Replacement target {${fieldName}} not found in metadata fields`);
|
|
117
111
|
}
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
120
|
-
errors.push(`replacements.json: ${err.message}`);
|
|
121
112
|
}
|
|
122
113
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
errors.push('replacements.json not found (required for runnable recipes)');
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
warnings.push('replacements.json not found (required for runnable recipes)');
|
|
129
|
-
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
errors.push(`replacements.json: ${err.message}`);
|
|
130
116
|
}
|
|
131
117
|
// Validate clean.json if present
|
|
132
118
|
const cleanPath = join(recipeDir, 'clean.json');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipe.js","sourceRoot":"","sources":["../../../src/core/validation/recipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAU9D,gEAAgE;AAChE,MAAM,MAAM,GAAG,uBAAuB,CAAC;AACvC,iEAAiE;AACjE,MAAM,YAAY,GAAG,YAAY,CAAC;AAClC,wDAAwD;AACxD,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAiB,EACjB,QAAgB,EAChB,OAA8B;IAE9B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,KAAK,CAAC;IAExC,mDAAmD;IACnD,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACzE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,oCAAoC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IACtH,CAAC;IAED,oBAAoB;IACpB,MAAM,UAAU,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACvE,CAAC;IAED,uEAAuE;IACvE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/E,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC;IACzE,MAAM,UAAU,GAAG,CAAC,eAAe,CAAC;IAEpC,oCAAoC;IACpC,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAChD,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,
|
|
1
|
+
{"version":3,"file":"recipe.js","sourceRoot":"","sources":["../../../src/core/validation/recipe.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -170,3 +170,12 @@ Use `list_templates` (MCP) or `list --json` (CLI) for the latest inventory and f
|
|
|
170
170
|
- All templates produce Word DOCX files preserving original formatting
|
|
171
171
|
- Templates are licensed by their respective authors (CC-BY-4.0 or CC0-1.0)
|
|
172
172
|
- This tool does not provide legal advice — consult an attorney
|
|
173
|
+
|
|
174
|
+
## Bespoke edits (beyond template fields)
|
|
175
|
+
|
|
176
|
+
If you need to edit boilerplate or add custom language that is not exposed as a template field,
|
|
177
|
+
use the `edit-docx-agreement` skill to surgically edit the generated DOCX and produce a
|
|
178
|
+
tracked-changes output for review. This requires a separately configured Safe Docx MCP server.
|
|
179
|
+
|
|
180
|
+
Note: templates licensed under CC-BY-ND-4.0 (e.g., YC SAFEs) can be filled for your own use
|
|
181
|
+
but must not be redistributed in modified form.
|
|
@@ -156,3 +156,12 @@ Use `list_templates` (MCP) or `list --json` (CLI) for the latest inventory and f
|
|
|
156
156
|
- Templates are licensed by their respective authors (CC-BY-4.0 or CC0-1.0)
|
|
157
157
|
- DPAs and BAAs are regulatory documents — ensure they meet your jurisdiction's specific requirements
|
|
158
158
|
- This tool does not provide legal advice — consult an attorney
|
|
159
|
+
|
|
160
|
+
## Bespoke edits (beyond template fields)
|
|
161
|
+
|
|
162
|
+
If you need to edit boilerplate or add custom language that is not exposed as a template field,
|
|
163
|
+
use the `edit-docx-agreement` skill to surgically edit the generated DOCX and produce a
|
|
164
|
+
tracked-changes output for review. This requires a separately configured Safe Docx MCP server.
|
|
165
|
+
|
|
166
|
+
Note: templates licensed under CC-BY-ND-4.0 (e.g., YC SAFEs) can be filled for your own use
|
|
167
|
+
but must not be redistributed in modified form.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Connectors
|
|
2
|
+
|
|
3
|
+
## OpenAgreements (for template filling)
|
|
4
|
+
|
|
5
|
+
Use the standard OpenAgreements connectors (remote MCP or local CLI) for fill operations.
|
|
6
|
+
See https://github.com/open-agreements/open-agreements/blob/main/skills/open-agreements/CONNECTORS.md for details.
|
|
7
|
+
|
|
8
|
+
## Safe Docx MCP (for surgical DOCX editing)
|
|
9
|
+
|
|
10
|
+
Safe Docx is a **separate MCP server** that must be configured independently.
|
|
11
|
+
It is not part of the OpenAgreements skill set.
|
|
12
|
+
|
|
13
|
+
The user must have Safe Docx MCP already set up in their agent environment.
|
|
14
|
+
If Safe Docx tools are not available, instruct the user to:
|
|
15
|
+
|
|
16
|
+
1. Visit https://github.com/UseJunior/safe-docx for setup instructions
|
|
17
|
+
2. Configure the Safe Docx MCP server in their agent's MCP settings
|
|
18
|
+
3. Restart their agent session
|
|
19
|
+
|
|
20
|
+
Do not instruct the agent to download or install packages at runtime.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: edit-docx-agreement
|
|
3
|
+
description: >-
|
|
4
|
+
Make bespoke edits to a DOCX agreement generated by OpenAgreements (or any existing DOCX),
|
|
5
|
+
using Safe Docx MCP tools for surgical, formatting-preserving edits and tracked-changes outputs.
|
|
6
|
+
license: MIT
|
|
7
|
+
compatibility: >-
|
|
8
|
+
Works with any agent. Requires a separately configured Safe Docx MCP server for document editing.
|
|
9
|
+
OpenAgreements fill capabilities require the OpenAgreements remote MCP or local CLI.
|
|
10
|
+
metadata:
|
|
11
|
+
author: open-agreements
|
|
12
|
+
version: "0.2.0"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# edit-docx-agreement
|
|
16
|
+
|
|
17
|
+
Use this skill when a user asks for **custom edits that are not exposed as template fields** in an OpenAgreements-generated (or any existing) DOCX agreement.
|
|
18
|
+
|
|
19
|
+
> **Interactivity note**: Always ask the user for missing inputs (file path, change intent, output preferences).
|
|
20
|
+
|
|
21
|
+
## Security model
|
|
22
|
+
|
|
23
|
+
This skill bridges two separate systems:
|
|
24
|
+
- **OpenAgreements** (remote MCP or local CLI) — for template filling. Follows the OpenAgreements zero-download security model.
|
|
25
|
+
- **Safe Docx** (local MCP server) — for surgical DOCX editing. Requires separate setup. This is **not** part of the OpenAgreements skill set and has its own trust/security model.
|
|
26
|
+
|
|
27
|
+
The agent must have Safe Docx MCP tools available to perform edits. If Safe Docx tools are not detected, inform the user and provide setup guidance (see Connectors).
|
|
28
|
+
|
|
29
|
+
## Decision rule: refill vs edit vs both
|
|
30
|
+
|
|
31
|
+
1. **Field-only changes** (e.g., party name, date, amount, valuation cap):
|
|
32
|
+
Re-run OpenAgreements `fill_template` with the updated field values. No Safe Docx needed.
|
|
33
|
+
|
|
34
|
+
2. **Boilerplate-only changes** (e.g., custom clause, modified standard language):
|
|
35
|
+
Use Safe Docx MCP tools to surgically edit the existing DOCX.
|
|
36
|
+
|
|
37
|
+
3. **Mixed changes** (field updates + bespoke edits):
|
|
38
|
+
Re-fill via OpenAgreements first (to get a clean base with updated fields), save the output locally, then use Safe Docx to apply bespoke edits on the fresh file.
|
|
39
|
+
|
|
40
|
+
## Execution
|
|
41
|
+
|
|
42
|
+
### Step 0: Confirm you have a local .docx file path
|
|
43
|
+
|
|
44
|
+
- If OpenAgreements was run via remote MCP, the fill response returns a download URL (with `expires_at`). Save the DOCX to a local path immediately.
|
|
45
|
+
- If the download link has expired, re-run `fill_template` to get a fresh URL.
|
|
46
|
+
- If OpenAgreements was run via local CLI, use the output file path directly.
|
|
47
|
+
|
|
48
|
+
### Step 1: Verify Safe Docx MCP is available
|
|
49
|
+
|
|
50
|
+
Check whether Safe Docx tools (e.g., `read_file`, `replace_text`, `apply_plan`) are available in the current session.
|
|
51
|
+
|
|
52
|
+
- **If available**: proceed to Step 2.
|
|
53
|
+
- **If not available**: inform the user that Safe Docx MCP is required for bespoke edits and provide setup instructions from the Connectors file. Stop here until the user configures it.
|
|
54
|
+
|
|
55
|
+
### Step 2: Apply the decision rule
|
|
56
|
+
|
|
57
|
+
Follow the routing logic above (field-only / boilerplate-only / mixed).
|
|
58
|
+
|
|
59
|
+
For Safe Docx edits:
|
|
60
|
+
- Use `read_file` to locate target paragraphs
|
|
61
|
+
- Use `replace_text` or `insert_paragraph` for surgical changes
|
|
62
|
+
- Use `apply_plan` for batch edits (fails safely if any step is invalid)
|
|
63
|
+
- Re-read edited paragraphs to verify changes
|
|
64
|
+
|
|
65
|
+
### Step 3: Deliver reviewable outputs
|
|
66
|
+
|
|
67
|
+
Use Safe Docx `download` to save:
|
|
68
|
+
- A **tracked-changes** DOCX for legal review
|
|
69
|
+
- A **clean** DOCX for signing (optional but recommended)
|
|
70
|
+
|
|
71
|
+
Summarize edits for the user (paragraph IDs, before/after text).
|
|
72
|
+
|
|
73
|
+
## Licensing note
|
|
74
|
+
|
|
75
|
+
Some templates (notably YC SAFEs) are licensed under CC-BY-ND-4.0. You can fill them for your own use but must not redistribute modified versions of the template itself. The filled output may constitute an "adapted work" — do not redistribute your filled output publicly without reviewing the license terms. See `docs/licensing.md` for details.
|
|
76
|
+
|
|
77
|
+
This tool does not provide legal advice — consult an attorney.
|
|
@@ -155,3 +155,12 @@ Use `list_templates` (MCP) or `list --json` (CLI) for the latest inventory and f
|
|
|
155
155
|
- OpenAgreements employment templates are licensed under CC-BY-4.0
|
|
156
156
|
- These templates are designed for US at-will employment — state-specific laws may apply
|
|
157
157
|
- This tool does not provide legal advice — consult an attorney
|
|
158
|
+
|
|
159
|
+
## Bespoke edits (beyond template fields)
|
|
160
|
+
|
|
161
|
+
If you need to edit boilerplate or add custom language that is not exposed as a template field,
|
|
162
|
+
use the `edit-docx-agreement` skill to surgically edit the generated DOCX and produce a
|
|
163
|
+
tracked-changes output for review. This requires a separately configured Safe Docx MCP server.
|
|
164
|
+
|
|
165
|
+
Note: templates licensed under CC-BY-ND-4.0 (e.g., YC SAFEs) can be filled for your own use
|
|
166
|
+
but must not be redistributed in modified form.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Connectors
|
|
2
|
+
|
|
3
|
+
## How tool references work
|
|
4
|
+
|
|
5
|
+
This skill uses `~~category` placeholders for optional integrations. The skill works without any connectors configured — they enhance the experience when available.
|
|
6
|
+
|
|
7
|
+
## Connectors for this skill
|
|
8
|
+
|
|
9
|
+
| Category | Placeholder | Recommended server | Other options |
|
|
10
|
+
|----------|-------------|-------------------|---------------|
|
|
11
|
+
| Compliance data | `~~compliance` | Compliance MCP server (planned — not yet available) | Local `compliance/` directory files |
|
|
12
|
+
|
|
13
|
+
### Local compliance data (current default)
|
|
14
|
+
|
|
15
|
+
If the `compliance/` directory exists with evidence status files, the skill reads those directly. No MCP server needed — just ensure evidence files in `compliance/evidence/*.md` are up to date.
|
|
16
|
+
|
|
17
|
+
### Compliance MCP server (planned)
|
|
18
|
+
|
|
19
|
+
A dedicated compliance MCP server with automated gap detection and evidence freshness tracking is planned but not yet available. When released, it will be installable as a standard MCP server. Until then, the skill operates in local-data or reference-only mode.
|
|
20
|
+
|
|
21
|
+
### Fallback: Reference only
|
|
22
|
+
|
|
23
|
+
Without any connector, the skill uses embedded checklists and CLI command reference. No organization-specific evidence status is available in this mode.
|