djournal 0.1.0 → 0.3.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.
@@ -90,6 +90,47 @@ function mergeHookConfig(current, fragment) {
90
90
  return { value: next, injected };
91
91
  }
92
92
 
93
+ function appendUnique(target, values) {
94
+ const injected = [];
95
+ for (const value of values || []) {
96
+ if (!target.some((candidate) => equal(candidate, value))) {
97
+ const copy = structuredClone(value);
98
+ target.push(copy);
99
+ injected.push(copy);
100
+ }
101
+ }
102
+ return injected;
103
+ }
104
+
105
+ function mergePermissionsConfig(current, fragment) {
106
+ const next = structuredClone(current);
107
+ const permissions = fragment.permissions || {};
108
+ const injected = {};
109
+ if (Array.isArray(permissions.additionalDirectories)) {
110
+ next.permissions ||= {};
111
+ next.permissions.additionalDirectories ||= [];
112
+ const additions = appendUnique(next.permissions.additionalDirectories, permissions.additionalDirectories);
113
+ if (additions.length) injected.additionalDirectories = additions;
114
+ }
115
+ if (Array.isArray(permissions.allow)) {
116
+ next.permissions ||= {};
117
+ next.permissions.allow ||= [];
118
+ const additions = appendUnique(next.permissions.allow, permissions.allow);
119
+ if (additions.length) injected.allow = additions;
120
+ }
121
+ return { value: next, injected };
122
+ }
123
+
124
+ function mergeConfigFragment(current, fragment) {
125
+ const hook = mergeHookConfig(current, fragment);
126
+ const permissions = mergePermissionsConfig(hook.value, fragment);
127
+ return {
128
+ value: permissions.value,
129
+ injected: hook.injected,
130
+ injectedPermissions: permissions.injected,
131
+ };
132
+ }
133
+
93
134
  function removeHookConfig(current, injected) {
94
135
  const next = structuredClone(current);
95
136
  const conflicts = [];
@@ -110,6 +151,35 @@ function removeHookConfig(current, injected) {
110
151
  return { value: next, conflicts };
111
152
  }
112
153
 
154
+ function removePermissionsConfig(current, injected) {
155
+ const next = structuredClone(current);
156
+ const conflicts = [];
157
+ for (const [key, values] of Object.entries(injected || {})) {
158
+ const existing = next.permissions?.[key];
159
+ if (!Array.isArray(existing)) {
160
+ conflicts.push(`permissions.${key}`);
161
+ continue;
162
+ }
163
+ for (const value of values) {
164
+ const index = existing.findIndex((candidate) => equal(candidate, value));
165
+ if (index === -1) conflicts.push(`permissions.${key}`);
166
+ else existing.splice(index, 1);
167
+ }
168
+ if (existing.length === 0) delete next.permissions[key];
169
+ }
170
+ if (next.permissions && Object.keys(next.permissions).length === 0) delete next.permissions;
171
+ return { value: next, conflicts };
172
+ }
173
+
174
+ function removeConfigFragment(current, injected, injectedPermissions) {
175
+ const hook = removeHookConfig(current, injected);
176
+ const permissions = removePermissionsConfig(hook.value, injectedPermissions);
177
+ return {
178
+ value: permissions.value,
179
+ conflicts: [...hook.conflicts, ...permissions.conflicts],
180
+ };
181
+ }
182
+
113
183
  module.exports = {
114
184
  BEGIN,
115
185
  END,
@@ -118,8 +188,12 @@ module.exports = {
118
188
  equal,
119
189
  hasManagedBlock,
120
190
  managedBlock,
191
+ mergeConfigFragment,
121
192
  mergeHookConfig,
193
+ mergePermissionsConfig,
194
+ removeConfigFragment,
122
195
  removeHookConfig,
196
+ removePermissionsConfig,
123
197
  removeManagedBlock,
124
198
  upsertManagedBlock,
125
199
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "djournal",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Durable project memory for coding agents, stored as linked Markdown",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -15,6 +15,7 @@
15
15
  "CLAUDE.md",
16
16
  "LICENSE",
17
17
  "bin/",
18
+ "docs/",
18
19
  "install.sh",
19
20
  "lib/",
20
21
  "spec.md"
@@ -22,6 +23,7 @@
22
23
  "scripts": {
23
24
  "check:package": "node scripts/check-package.cjs",
24
25
  "check:pr-title": "node scripts/check-pr-title.js",
26
+ "link:global": "npm link",
25
27
  "release": "semantic-release",
26
28
  "test": "node tests/journal-hook.test.js && node tests/installer/installer.test.js && node tests/release-policy.test.js && npm run check:package",
27
29
  "prepublishOnly": "npm test"