@bookedsolid/reagent 0.13.2 → 0.14.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 +149 -6
- package/dist/cli/commands/init/claude-md.d.ts +5 -0
- package/dist/cli/commands/init/claude-md.d.ts.map +1 -1
- package/dist/cli/commands/init/claude-md.js +21 -1
- package/dist/cli/commands/init/claude-md.js.map +1 -1
- package/dist/cli/commands/init/index.d.ts.map +1 -1
- package/dist/cli/commands/init/index.js +16 -4
- package/dist/cli/commands/init/index.js.map +1 -1
- package/dist/cli/commands/init/mcp-config.js +6 -6
- package/dist/cli/commands/init/mcp-config.js.map +1 -1
- package/dist/cli/commands/init/obsidian.d.ts +16 -0
- package/dist/cli/commands/init/obsidian.d.ts.map +1 -0
- package/dist/cli/commands/init/obsidian.js +95 -0
- package/dist/cli/commands/init/obsidian.js.map +1 -0
- package/dist/cli/commands/init/policy.d.ts.map +1 -1
- package/dist/cli/commands/init/policy.js +10 -1
- package/dist/cli/commands/init/policy.js.map +1 -1
- package/dist/cli/commands/obsidian.d.ts +2 -0
- package/dist/cli/commands/obsidian.d.ts.map +1 -0
- package/dist/cli/commands/obsidian.js +187 -0
- package/dist/cli/commands/obsidian.js.map +1 -0
- package/dist/cli/commands/upgrade-policy.d.ts +17 -0
- package/dist/cli/commands/upgrade-policy.d.ts.map +1 -0
- package/dist/cli/commands/upgrade-policy.js +123 -0
- package/dist/cli/commands/upgrade-policy.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -1
- package/dist/cli/commands/upgrade.js +8 -26
- package/dist/cli/commands/upgrade.js.map +1 -1
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/gateway/native-tools.d.ts.map +1 -1
- package/dist/gateway/native-tools.js +39 -0
- package/dist/gateway/native-tools.js.map +1 -1
- package/dist/obsidian/cli.d.ts +49 -0
- package/dist/obsidian/cli.d.ts.map +1 -0
- package/dist/obsidian/cli.js +128 -0
- package/dist/obsidian/cli.js.map +1 -0
- package/dist/obsidian/index.d.ts +7 -0
- package/dist/obsidian/index.d.ts.map +1 -0
- package/dist/obsidian/index.js +5 -0
- package/dist/obsidian/index.js.map +1 -0
- package/dist/obsidian/kanban-generator.d.ts +9 -0
- package/dist/obsidian/kanban-generator.d.ts.map +1 -0
- package/dist/obsidian/kanban-generator.js +63 -0
- package/dist/obsidian/kanban-generator.js.map +1 -0
- package/dist/obsidian/vault-config.d.ts +142 -0
- package/dist/obsidian/vault-config.d.ts.map +1 -0
- package/dist/obsidian/vault-config.js +92 -0
- package/dist/obsidian/vault-config.js.map +1 -0
- package/dist/obsidian/vault-writer.d.ts +52 -0
- package/dist/obsidian/vault-writer.d.ts.map +1 -0
- package/dist/obsidian/vault-writer.js +166 -0
- package/dist/obsidian/vault-writer.js.map +1 -0
- package/dist/types/policy.d.ts +4 -0
- package/dist/types/policy.d.ts.map +1 -1
- package/hooks/dangerous-bash-interceptor.sh +43 -0
- package/hooks/reagent-obsidian-journal.sh +69 -0
- package/hooks/reagent-obsidian-precompact.sh +88 -0
- package/hooks/reagent-obsidian-tasks.sh +126 -0
- package/package.json +2 -2
- package/profiles/bst-internal.json +1 -1
- package/profiles/client-engagement.json +2 -2
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { loadObsidianConfig } from './vault-config.js';
|
|
4
|
+
import { generateKanban } from './kanban-generator.js';
|
|
5
|
+
import { ObsidianCli } from './cli.js';
|
|
6
|
+
import { TaskStore } from '../pm/task-store.js';
|
|
7
|
+
/**
|
|
8
|
+
* Obsidian vault writer — writes markdown files directly to the vault.
|
|
9
|
+
* Obsidian auto-refreshes via filesystem watcher.
|
|
10
|
+
*
|
|
11
|
+
* All methods return silently when not configured.
|
|
12
|
+
* Pattern: DiscordNotifier (fail-silent, config-gated).
|
|
13
|
+
*/
|
|
14
|
+
export class VaultWriter {
|
|
15
|
+
config;
|
|
16
|
+
store;
|
|
17
|
+
constructor(baseDir) {
|
|
18
|
+
this.config = loadObsidianConfig(baseDir);
|
|
19
|
+
this.store = new TaskStore(baseDir);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check whether Obsidian vault sync is enabled.
|
|
23
|
+
*/
|
|
24
|
+
isEnabled() {
|
|
25
|
+
return this.config !== null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get resolved config for status display. Returns null if not configured.
|
|
29
|
+
*/
|
|
30
|
+
getConfig() {
|
|
31
|
+
return this.config;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sync the Kanban board to the vault.
|
|
35
|
+
* Writes only if sync.kanban is enabled.
|
|
36
|
+
*/
|
|
37
|
+
syncKanban(dryRun = false) {
|
|
38
|
+
if (!this.config) {
|
|
39
|
+
return { target: 'kanban', written: false };
|
|
40
|
+
}
|
|
41
|
+
if (!this.config.sync.kanban) {
|
|
42
|
+
return { target: 'kanban', written: false, error: 'kanban sync not enabled in config' };
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const tasks = this.store.listTasks();
|
|
46
|
+
const markdown = generateKanban(tasks);
|
|
47
|
+
const outputPath = path.join(this.config.vault_path, this.config.paths.kanban);
|
|
48
|
+
if (!dryRun) {
|
|
49
|
+
// Ensure parent directory exists
|
|
50
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
51
|
+
fs.writeFileSync(outputPath, markdown, 'utf8');
|
|
52
|
+
}
|
|
53
|
+
return { target: 'kanban', written: !dryRun, path: outputPath };
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return { target: 'kanban', written: false, error: 'Failed to write kanban' };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Sync context dump to the vault.
|
|
61
|
+
* Placeholder for Phase 3.
|
|
62
|
+
*/
|
|
63
|
+
syncContextDump(dryRun = false) {
|
|
64
|
+
if (!this.config) {
|
|
65
|
+
return { target: 'context', written: false };
|
|
66
|
+
}
|
|
67
|
+
if (!this.config.sync.context_dump) {
|
|
68
|
+
return {
|
|
69
|
+
target: 'context',
|
|
70
|
+
written: false,
|
|
71
|
+
error: 'context_dump sync not enabled in config',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Phase 3: context-dumper.ts will be wired here
|
|
75
|
+
void dryRun;
|
|
76
|
+
return { target: 'context', written: false, error: 'Not yet implemented' };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Sync wiki pages to the vault.
|
|
80
|
+
* Placeholder for Phase 4.
|
|
81
|
+
*/
|
|
82
|
+
syncWiki(dryRun = false) {
|
|
83
|
+
if (!this.config) {
|
|
84
|
+
return { target: 'wiki', written: false };
|
|
85
|
+
}
|
|
86
|
+
if (!this.config.sync.wiki_refresh) {
|
|
87
|
+
return { target: 'wiki', written: false, error: 'wiki_refresh sync not enabled in config' };
|
|
88
|
+
}
|
|
89
|
+
// Phase 4: wiki-generator.ts will be wired here
|
|
90
|
+
void dryRun;
|
|
91
|
+
return { target: 'wiki', written: false, error: 'Not yet implemented' };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Sync tasks as individual Obsidian notes via the CLI.
|
|
95
|
+
* Writes only if sync.tasks is enabled and the Obsidian CLI is available.
|
|
96
|
+
*/
|
|
97
|
+
syncTasks(dryRun = false) {
|
|
98
|
+
if (!this.config) {
|
|
99
|
+
return { target: 'tasks', written: false };
|
|
100
|
+
}
|
|
101
|
+
if (!this.config.sync.tasks) {
|
|
102
|
+
return { target: 'tasks', written: false, error: 'tasks sync not enabled in config' };
|
|
103
|
+
}
|
|
104
|
+
if (!this.config.vault_name) {
|
|
105
|
+
return { target: 'tasks', written: false, error: 'vault_name not set in config' };
|
|
106
|
+
}
|
|
107
|
+
if (!ObsidianCli.isAvailable()) {
|
|
108
|
+
return { target: 'tasks', written: false, error: 'Obsidian CLI not available' };
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const tasks = this.store.listTasks();
|
|
112
|
+
if (tasks.length === 0) {
|
|
113
|
+
return { target: 'tasks', written: false, error: 'No tasks to sync' };
|
|
114
|
+
}
|
|
115
|
+
if (dryRun) {
|
|
116
|
+
return { target: 'tasks', written: false, path: `${tasks.length} tasks would be synced` };
|
|
117
|
+
}
|
|
118
|
+
const cli = new ObsidianCli(this.config.vault_name);
|
|
119
|
+
const tasksPath = this.config.paths.tasks;
|
|
120
|
+
let synced = 0;
|
|
121
|
+
for (const task of tasks) {
|
|
122
|
+
const noteName = `${task.id} ${task.title}`;
|
|
123
|
+
const content = [
|
|
124
|
+
'---',
|
|
125
|
+
'reagent_managed: true',
|
|
126
|
+
`task_id: "${task.id}"`,
|
|
127
|
+
`status: "${task.status}"`,
|
|
128
|
+
`urgency: "${task.urgency}"`,
|
|
129
|
+
`assignee: "${task.assignee || 'unassigned'}"`,
|
|
130
|
+
'---',
|
|
131
|
+
'',
|
|
132
|
+
`# ${task.title}`,
|
|
133
|
+
'',
|
|
134
|
+
`- **ID:** ${task.id}`,
|
|
135
|
+
`- **Status:** ${task.status}`,
|
|
136
|
+
`- **Urgency:** ${task.urgency}`,
|
|
137
|
+
`- **Assignee:** ${task.assignee || 'unassigned'}`,
|
|
138
|
+
'',
|
|
139
|
+
].join('\n');
|
|
140
|
+
if (cli.createNote(noteName, content, { path: tasksPath })) {
|
|
141
|
+
synced++;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
target: 'tasks',
|
|
146
|
+
written: synced > 0,
|
|
147
|
+
path: `${synced}/${tasks.length} tasks synced to ${tasksPath}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return { target: 'tasks', written: false, error: 'Failed to sync tasks' };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Sync all enabled targets.
|
|
156
|
+
*/
|
|
157
|
+
syncAll(dryRun = false) {
|
|
158
|
+
return [
|
|
159
|
+
this.syncKanban(dryRun),
|
|
160
|
+
this.syncContextDump(dryRun),
|
|
161
|
+
this.syncWiki(dryRun),
|
|
162
|
+
this.syncTasks(dryRun),
|
|
163
|
+
];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=vault-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-writer.js","sourceRoot":"","sources":["../../src/obsidian/vault-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAA+B,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAShD;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IACL,MAAM,CAAgC;IACtC,KAAK,CAAY;IAElC,YAAY,OAAe;QACzB,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,MAAM,GAAG,KAAK;QACvB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC7B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC;QAC1F,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;YACvC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAE/E,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,iCAAiC;gBACjC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC5D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACjD,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAClE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;QAC/E,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,MAAM,GAAG,KAAK;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACnC,OAAO;gBACL,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,yCAAyC;aACjD,CAAC;QACJ,CAAC;QAED,gDAAgD;QAChD,KAAK,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC7E,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,MAAM,GAAG,KAAK;QACrB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACnC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC;QAC9F,CAAC;QAED,gDAAgD;QAChD,KAAK,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC1E,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,MAAM,GAAG,KAAK;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;QAClF,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;YACxE,CAAC;YAED,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,wBAAwB,EAAE,CAAC;YAC5F,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAC1C,IAAI,MAAM,GAAG,CAAC,CAAC;YAEf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC5C,MAAM,OAAO,GAAG;oBACd,KAAK;oBACL,uBAAuB;oBACvB,aAAa,IAAI,CAAC,EAAE,GAAG;oBACvB,YAAY,IAAI,CAAC,MAAM,GAAG;oBAC1B,aAAa,IAAI,CAAC,OAAO,GAAG;oBAC5B,cAAc,IAAI,CAAC,QAAQ,IAAI,YAAY,GAAG;oBAC9C,KAAK;oBACL,EAAE;oBACF,KAAK,IAAI,CAAC,KAAK,EAAE;oBACjB,EAAE;oBACF,aAAa,IAAI,CAAC,EAAE,EAAE;oBACtB,iBAAiB,IAAI,CAAC,MAAM,EAAE;oBAC9B,kBAAkB,IAAI,CAAC,OAAO,EAAE;oBAChC,mBAAmB,IAAI,CAAC,QAAQ,IAAI,YAAY,EAAE;oBAClD,EAAE;iBACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEb,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;oBAC3D,MAAM,EAAE,CAAC;gBACX,CAAC;YACH,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,MAAM,GAAG,CAAC;gBACnB,IAAI,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,MAAM,oBAAoB,SAAS,EAAE;aAC/D,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;QAC5E,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,MAAM,GAAG,KAAK;QACpB,OAAO;YACL,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YACvB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACrB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SACvB,CAAC;IACJ,CAAC;CACF"}
|
package/dist/types/policy.d.ts
CHANGED
|
@@ -11,5 +11,9 @@ export interface Policy {
|
|
|
11
11
|
blocked_paths: string[];
|
|
12
12
|
notification_channel: string;
|
|
13
13
|
injection_detection?: 'block' | 'warn';
|
|
14
|
+
context_protection?: {
|
|
15
|
+
delegate_to_subagent: string[];
|
|
16
|
+
max_bash_output_lines?: number;
|
|
17
|
+
};
|
|
14
18
|
}
|
|
15
19
|
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/types/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,aAAa,CAAC;IAC9B,kBAAkB,EAAE,aAAa,CAAC;IAClC,iCAAiC,EAAE,OAAO,CAAC;IAC3C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAE7B,mBAAmB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/types/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,aAAa,CAAC;IAC9B,kBAAkB,EAAE,aAAa,CAAC;IAClC,iCAAiC,EAAE,OAAO,CAAC;IAC3C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAE7B,mBAAmB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAEvC,kBAAkB,CAAC,EAAE;QACnB,oBAAoB,EAAE,MAAM,EAAE,CAAC;QAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;CACH"}
|
|
@@ -261,6 +261,49 @@ if printf '%s' "$CMD" | grep -qiE '(alias|function)[[:space:]]+[a-zA-Z_]+.*(--(n
|
|
|
261
261
|
"Alt: Do not wrap bypass patterns in aliases or functions."
|
|
262
262
|
fi
|
|
263
263
|
|
|
264
|
+
# H17: context_protection — block commands that should be delegated to subagents
|
|
265
|
+
# Reads context_protection.delegate_to_subagent from .reagent/policy.yaml.
|
|
266
|
+
# These commands produce excessive output that exhausts coordinator context windows.
|
|
267
|
+
POLICY_FILE="${REAGENT_ROOT}/.reagent/policy.yaml"
|
|
268
|
+
if [[ -f "$POLICY_FILE" ]]; then
|
|
269
|
+
DELEGATE_PATTERNS=()
|
|
270
|
+
IN_DELEGATE_BLOCK=0
|
|
271
|
+
while IFS= read -r line; do
|
|
272
|
+
if printf '%s' "$line" | grep -qE '^[[:space:]]*delegate_to_subagent:'; then
|
|
273
|
+
# Check for inline empty array
|
|
274
|
+
if printf '%s' "$line" | grep -qE 'delegate_to_subagent:[[:space:]]*\[\]'; then
|
|
275
|
+
break
|
|
276
|
+
fi
|
|
277
|
+
IN_DELEGATE_BLOCK=1
|
|
278
|
+
continue
|
|
279
|
+
fi
|
|
280
|
+
if [[ $IN_DELEGATE_BLOCK -eq 1 ]]; then
|
|
281
|
+
# Block sequence items start with " - "
|
|
282
|
+
if printf '%s' "$line" | grep -qE '^[[:space:]]*-[[:space:]]'; then
|
|
283
|
+
pattern=$(printf '%s' "$line" | sed "s/^[[:space:]]*-[[:space:]]*//; s/^[\"']//; s/[\"']$//")
|
|
284
|
+
if [[ -n "$pattern" ]]; then
|
|
285
|
+
DELEGATE_PATTERNS+=("$pattern")
|
|
286
|
+
fi
|
|
287
|
+
else
|
|
288
|
+
# Non-continuation line = end of block
|
|
289
|
+
break
|
|
290
|
+
fi
|
|
291
|
+
fi
|
|
292
|
+
done < "$POLICY_FILE"
|
|
293
|
+
|
|
294
|
+
for pattern in "${DELEGATE_PATTERNS[@]+"${DELEGATE_PATTERNS[@]}"}"; do
|
|
295
|
+
# Use fixed-string match — these are command prefixes, not regex
|
|
296
|
+
if printf '%s' "$CMD" | grep -qF "$pattern"; then
|
|
297
|
+
add_high \
|
|
298
|
+
"Context protection — command must run in a subagent" \
|
|
299
|
+
"This command produces excessive output that will exhaust the coordinator context window. Delegate it to a subagent instead of running it directly." \
|
|
300
|
+
"Alt: Use the Agent tool to delegate: Agent(subagent_type: 'qa-engineer-automation', prompt: 'Run $pattern and report pass/fail summary only.')" \
|
|
301
|
+
"Alt: The context_protection policy in .reagent/policy.yaml lists commands that must be delegated."
|
|
302
|
+
break
|
|
303
|
+
fi
|
|
304
|
+
done
|
|
305
|
+
fi
|
|
306
|
+
|
|
264
307
|
# ── 10. MEDIUM severity checks ────────────────────────────────────────────────
|
|
265
308
|
|
|
266
309
|
# M1: npm install --force
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# reagent-obsidian-journal.sh — Session journaling to Obsidian daily note
|
|
3
|
+
#
|
|
4
|
+
# Hook type: Stop (fires when Claude Code session ends)
|
|
5
|
+
# Appends session summary to the project's daily note via Obsidian CLI.
|
|
6
|
+
# Fail-silent: exits 0 even on error (non-blocking).
|
|
7
|
+
#
|
|
8
|
+
# Requires:
|
|
9
|
+
# - /usr/local/bin/obsidian CLI installed
|
|
10
|
+
# - REAGENT_OBSIDIAN_VAULT env var set
|
|
11
|
+
# - obsidian_vault.sync.journal: true in .reagent/gateway.yaml
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
OBSIDIAN_CLI="/usr/local/bin/obsidian"
|
|
16
|
+
POLICY_DIR=".reagent"
|
|
17
|
+
GATEWAY="${POLICY_DIR}/gateway.yaml"
|
|
18
|
+
TASK_STORE="${POLICY_DIR}/tasks.jsonl"
|
|
19
|
+
|
|
20
|
+
# ── Guard: CLI available ──────────────────────────────────────────────
|
|
21
|
+
if [[ ! -x "$OBSIDIAN_CLI" ]]; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# ── Guard: gateway.yaml exists ────────────────────────────────────────
|
|
26
|
+
if [[ ! -f "$GATEWAY" ]]; then
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# ── Guard: journal sync enabled ──────────────────────────────────────
|
|
31
|
+
# Anchored grep — must be indented (under sync: block), avoids matching comments
|
|
32
|
+
if ! grep -qE '^\s+journal:\s*true' "$GATEWAY" 2>/dev/null; then
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# ── Resolve vault name ────────────────────────────────────────────────
|
|
37
|
+
VAULT_NAME=$(grep 'vault_name:' "$GATEWAY" 2>/dev/null | head -1 | sed "s/.*vault_name:\s*['\"]*//" | sed "s/['\"].*//")
|
|
38
|
+
if [[ -z "$VAULT_NAME" ]]; then
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# ── Build session summary ─────────────────────────────────────────────
|
|
43
|
+
PROJECT_NAME=$(basename "$(pwd)")
|
|
44
|
+
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
|
|
45
|
+
SESSION_ID="${RANDOM}"
|
|
46
|
+
|
|
47
|
+
SUMMARY="### ${PROJECT_NAME} — Session ${SESSION_ID} (${TIMESTAMP})\n"
|
|
48
|
+
|
|
49
|
+
# Materialize task state if task store exists
|
|
50
|
+
if [[ -f "$TASK_STORE" ]]; then
|
|
51
|
+
COMPLETED=$(grep -c '"completed"' "$TASK_STORE" 2>/dev/null || echo "0")
|
|
52
|
+
IN_PROGRESS=$(grep -c '"started"' "$TASK_STORE" 2>/dev/null || echo "0")
|
|
53
|
+
BLOCKED=$(grep -c '"blocked"' "$TASK_STORE" 2>/dev/null || echo "0")
|
|
54
|
+
CREATED=$(grep -c '"created"' "$TASK_STORE" 2>/dev/null || echo "0")
|
|
55
|
+
|
|
56
|
+
SUMMARY="${SUMMARY}- Completed: ${COMPLETED}\n"
|
|
57
|
+
SUMMARY="${SUMMARY}- In Progress: ${IN_PROGRESS}\n"
|
|
58
|
+
SUMMARY="${SUMMARY}- Blocked: ${BLOCKED}\n"
|
|
59
|
+
SUMMARY="${SUMMARY}- Backlog: ${CREATED}\n"
|
|
60
|
+
else
|
|
61
|
+
SUMMARY="${SUMMARY}- No task store found\n"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
SUMMARY="${SUMMARY}\n---\n"
|
|
65
|
+
|
|
66
|
+
# ── Append to daily note ──────────────────────────────────────────────
|
|
67
|
+
"$OBSIDIAN_CLI" daily:append --vault "$VAULT_NAME" -- "$(echo -e "$SUMMARY")" 2>/dev/null || true
|
|
68
|
+
|
|
69
|
+
exit 0
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# reagent-obsidian-precompact.sh — Knowledge extraction before context compaction
|
|
3
|
+
#
|
|
4
|
+
# Hook type: PreCompact (fires before Claude Code compacts context)
|
|
5
|
+
# Spawns a subprocess to extract durable knowledge from the transcript
|
|
6
|
+
# and creates a session knowledge note in Obsidian.
|
|
7
|
+
#
|
|
8
|
+
# Disabled by default (precompact: false in gateway.yaml).
|
|
9
|
+
# Fail-silent: exits 0 even on error (non-blocking).
|
|
10
|
+
#
|
|
11
|
+
# Requires:
|
|
12
|
+
# - /usr/local/bin/obsidian CLI installed
|
|
13
|
+
# - REAGENT_OBSIDIAN_VAULT env var set
|
|
14
|
+
# - obsidian_vault.sync.precompact: true in .reagent/gateway.yaml
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
OBSIDIAN_CLI="/usr/local/bin/obsidian"
|
|
19
|
+
POLICY_DIR=".reagent"
|
|
20
|
+
GATEWAY="${POLICY_DIR}/gateway.yaml"
|
|
21
|
+
|
|
22
|
+
# ── Guard: CLI available ──────────────────────────────────────────────
|
|
23
|
+
if [[ ! -x "$OBSIDIAN_CLI" ]]; then
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# ── Guard: gateway.yaml exists ────────────────────────────────────────
|
|
28
|
+
if [[ ! -f "$GATEWAY" ]]; then
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# ── Guard: precompact sync enabled ───────────────────────────────────
|
|
33
|
+
# Anchored grep — must be indented (under sync: block), avoids matching comments
|
|
34
|
+
if ! grep -qE '^\s+precompact:\s*true' "$GATEWAY" 2>/dev/null; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# ── Resolve vault name and sessions path ──────────────────────────────
|
|
39
|
+
VAULT_NAME=$(grep 'vault_name:' "$GATEWAY" 2>/dev/null | head -1 | sed "s/.*vault_name:\s*['\"]*//" | sed "s/['\"].*//")
|
|
40
|
+
if [[ -z "$VAULT_NAME" ]]; then
|
|
41
|
+
exit 0
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
SESSIONS_PATH=$(grep 'sessions:' "$GATEWAY" 2>/dev/null | head -1 | sed "s/.*sessions:\s*['\"]*//" | sed "s/['\"].*//")
|
|
45
|
+
SESSIONS_PATH="${SESSIONS_PATH:-Wiki/Sessions}"
|
|
46
|
+
|
|
47
|
+
# ── Resolve engine ────────────────────────────────────────────────────
|
|
48
|
+
ENGINE=$(grep 'engine:' "$GATEWAY" 2>/dev/null | head -1 | sed "s/.*engine:\s*['\"]*//" | sed "s/['\"].*//")
|
|
49
|
+
ENGINE="${ENGINE:-claude}"
|
|
50
|
+
|
|
51
|
+
PROJECT_NAME=$(basename "$(pwd)")
|
|
52
|
+
DATE=$(date '+%Y-%m-%d')
|
|
53
|
+
SESSION_ID="${RANDOM}"
|
|
54
|
+
NOTE_NAME="${PROJECT_NAME} Session ${DATE} ${SESSION_ID}"
|
|
55
|
+
|
|
56
|
+
# ── Stub: knowledge extraction ────────────────────────────────────────
|
|
57
|
+
# TODO: Implement actual transcript extraction via claude subprocess or ollama
|
|
58
|
+
# For now, create a placeholder session note
|
|
59
|
+
|
|
60
|
+
CONTENT="---
|
|
61
|
+
reagent_managed: true
|
|
62
|
+
project: ${PROJECT_NAME}
|
|
63
|
+
date: ${DATE}
|
|
64
|
+
session_id: ${SESSION_ID}
|
|
65
|
+
engine: ${ENGINE}
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
# Session Knowledge — ${PROJECT_NAME}
|
|
69
|
+
|
|
70
|
+
*Auto-extracted at ${DATE} by reagent precompact hook.*
|
|
71
|
+
|
|
72
|
+
> Knowledge extraction engine: ${ENGINE}
|
|
73
|
+
> Status: stub — full extraction not yet implemented
|
|
74
|
+
|
|
75
|
+
## Decisions
|
|
76
|
+
|
|
77
|
+
## Discoveries
|
|
78
|
+
|
|
79
|
+
## Open Questions
|
|
80
|
+
"
|
|
81
|
+
|
|
82
|
+
"$OBSIDIAN_CLI" create \
|
|
83
|
+
--vault "$VAULT_NAME" \
|
|
84
|
+
--path "$SESSIONS_PATH" \
|
|
85
|
+
--name "$NOTE_NAME" \
|
|
86
|
+
-- "$CONTENT" 2>/dev/null || true
|
|
87
|
+
|
|
88
|
+
exit 0
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# reagent-obsidian-tasks.sh — Task sync to Obsidian individual notes
|
|
3
|
+
#
|
|
4
|
+
# Hook type: PostToolUse (fires after task_create, task_update MCP tools)
|
|
5
|
+
# Materializes task events as individual Obsidian notes with typed frontmatter.
|
|
6
|
+
# One-way sync: JSONL → Obsidian. Reverse sync deferred.
|
|
7
|
+
#
|
|
8
|
+
# Fail-silent: exits 0 even on error (non-blocking).
|
|
9
|
+
#
|
|
10
|
+
# Requires:
|
|
11
|
+
# - /usr/local/bin/obsidian CLI installed
|
|
12
|
+
# - REAGENT_OBSIDIAN_VAULT env var set
|
|
13
|
+
# - obsidian_vault.sync.tasks: true in .reagent/gateway.yaml
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
OBSIDIAN_CLI="/usr/local/bin/obsidian"
|
|
18
|
+
POLICY_DIR=".reagent"
|
|
19
|
+
GATEWAY="${POLICY_DIR}/gateway.yaml"
|
|
20
|
+
TASK_STORE="${POLICY_DIR}/tasks.jsonl"
|
|
21
|
+
|
|
22
|
+
# ── Guard: CLI available ──────────────────────────────────────────────
|
|
23
|
+
if [[ ! -x "$OBSIDIAN_CLI" ]]; then
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# ── Guard: gateway.yaml exists ────────────────────────────────────────
|
|
28
|
+
if [[ ! -f "$GATEWAY" ]]; then
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# ── Guard: tasks sync enabled ────────────────────────────────────────
|
|
33
|
+
# Match sync.tasks specifically — use awk to only match within the sync: block
|
|
34
|
+
if ! awk '/^\s+sync:/{found=1} found && /tasks:\s*true/{exit 0} END{exit 1}' "$GATEWAY" 2>/dev/null; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# ── Guard: task store exists ──────────────────────────────────────────
|
|
39
|
+
if [[ ! -f "$TASK_STORE" ]]; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# ── Resolve vault name and tasks path ─────────────────────────────────
|
|
44
|
+
VAULT_NAME=$(grep 'vault_name:' "$GATEWAY" 2>/dev/null | head -1 | sed "s/.*vault_name:\s*['\"]*//" | sed "s/['\"].*//")
|
|
45
|
+
if [[ -z "$VAULT_NAME" ]]; then
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Extract paths.tasks — use awk to match only within the paths: block (not sync:)
|
|
50
|
+
TASKS_PATH=$(awk '/^\s+paths:/{found=1} found && /tasks:/{print; exit}' "$GATEWAY" 2>/dev/null | sed "s/.*tasks:\s*['\"]*//" | sed "s/['\"].*//")
|
|
51
|
+
TASKS_PATH="${TASKS_PATH:-Tasks}"
|
|
52
|
+
|
|
53
|
+
PROJECT_NAME=$(basename "$(pwd)")
|
|
54
|
+
|
|
55
|
+
# ── Read tool result from stdin (Claude hook protocol) ────────────────
|
|
56
|
+
TOOL_RESULT=""
|
|
57
|
+
if [[ ! -t 0 ]]; then
|
|
58
|
+
TOOL_RESULT=$(cat 2>/dev/null || true)
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Extract task ID from the tool result JSON
|
|
62
|
+
TASK_ID=""
|
|
63
|
+
if [[ -n "$TOOL_RESULT" ]]; then
|
|
64
|
+
TASK_ID=$(echo "$TOOL_RESULT" | grep -o '"id"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# If we don't have a specific task ID, sync the most recent task
|
|
68
|
+
if [[ -z "$TASK_ID" ]]; then
|
|
69
|
+
TASK_ID=$(tail -1 "$TASK_STORE" | grep -o '"id"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
if [[ -z "$TASK_ID" ]]; then
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# ── Extract task data from JSONL ──────────────────────────────────────
|
|
77
|
+
# Get the latest event for this task
|
|
78
|
+
TASK_LINE=$(grep "\"$TASK_ID\"" "$TASK_STORE" | tail -1)
|
|
79
|
+
|
|
80
|
+
if [[ -z "$TASK_LINE" ]]; then
|
|
81
|
+
exit 0
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Extract fields (simple grep — avoids jq dependency)
|
|
85
|
+
TITLE=$(echo "$TASK_LINE" | grep -o '"title"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
|
|
86
|
+
STATUS=$(echo "$TASK_LINE" | grep -o '"status"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
|
|
87
|
+
URGENCY=$(echo "$TASK_LINE" | grep -o '"urgency"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
|
|
88
|
+
ASSIGNEE=$(echo "$TASK_LINE" | grep -o '"assignee"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
|
|
89
|
+
|
|
90
|
+
TITLE="${TITLE:-Untitled Task}"
|
|
91
|
+
STATUS="${STATUS:-created}"
|
|
92
|
+
URGENCY="${URGENCY:-normal}"
|
|
93
|
+
|
|
94
|
+
# ── Create/update note via Obsidian CLI ───────────────────────────────
|
|
95
|
+
NOTE_NAME="${TASK_ID} ${TITLE}"
|
|
96
|
+
|
|
97
|
+
CONTENT="---
|
|
98
|
+
reagent_managed: true
|
|
99
|
+
task_id: ${TASK_ID}
|
|
100
|
+
project: ${PROJECT_NAME}
|
|
101
|
+
status: ${STATUS}
|
|
102
|
+
urgency: ${URGENCY}
|
|
103
|
+
assignee: ${ASSIGNEE:-unassigned}
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
# ${TITLE}
|
|
107
|
+
|
|
108
|
+
- **ID:** ${TASK_ID}
|
|
109
|
+
- **Status:** ${STATUS}
|
|
110
|
+
- **Urgency:** ${URGENCY}
|
|
111
|
+
- **Assignee:** ${ASSIGNEE:-unassigned}
|
|
112
|
+
- **Project:** ${PROJECT_NAME}
|
|
113
|
+
"
|
|
114
|
+
|
|
115
|
+
# Create note (overwrites if exists)
|
|
116
|
+
"$OBSIDIAN_CLI" create \
|
|
117
|
+
--vault "$VAULT_NAME" \
|
|
118
|
+
--path "$TASKS_PATH" \
|
|
119
|
+
--name "$NOTE_NAME" \
|
|
120
|
+
-- "$CONTENT" 2>/dev/null || true
|
|
121
|
+
|
|
122
|
+
# Set properties via CLI for proper frontmatter handling
|
|
123
|
+
"$OBSIDIAN_CLI" property:set --vault "$VAULT_NAME" --file "${TASKS_PATH}/${NOTE_NAME}.md" \
|
|
124
|
+
--name "status" --value "$STATUS" 2>/dev/null || true
|
|
125
|
+
|
|
126
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bookedsolid/reagent",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.14.2",
|
|
4
|
+
"description": "Governance layer for Claude Code — policy enforcement, hook-based safety gates, and audit logging for AI-assisted projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Booked Solid Technology <oss@bookedsolid.tech> (https://bookedsolid.tech)",
|
|
7
7
|
"homepage": "https://github.com/bookedsolidtech/reagent#readme",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"huskyPreCommit": true,
|
|
7
7
|
"huskyPrePush": true,
|
|
8
8
|
"cursorRules": ["001-no-hallucination", "002-verify-before-act", "003-attribution"],
|
|
9
|
-
"blockedPaths": [".reagent/", ".env"],
|
|
9
|
+
"blockedPaths": [".reagent/policy.yaml", ".reagent/HALT", ".env"],
|
|
10
10
|
"gitignoreEntries": [".claude/agents/", ".claude/hooks/", ".claude/settings.json", "RESTART.md"],
|
|
11
11
|
"qualityGates": {
|
|
12
12
|
"commitReview": { "enabled": true, "trivialThreshold": 20, "significantThreshold": 200 },
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"huskyPreCommit": true,
|
|
7
7
|
"huskyPrePush": true,
|
|
8
8
|
"cursorRules": ["001-no-hallucination", "002-verify-before-act", "003-attribution"],
|
|
9
|
-
"blockedPaths": [".reagent/", ".github/workflows/", ".env", ".env.*"],
|
|
10
|
-
"gitignoreEntries": [".claude/
|
|
9
|
+
"blockedPaths": [".reagent/policy.yaml", ".reagent/HALT", ".github/workflows/", ".env", ".env.*"],
|
|
10
|
+
"gitignoreEntries": [".claude/hooks/", ".claude/settings.json", "RESTART.md"],
|
|
11
11
|
"qualityGates": {
|
|
12
12
|
"commitReview": { "enabled": true, "trivialThreshold": 20, "significantThreshold": 200 },
|
|
13
13
|
"pushReview": { "enabled": true },
|