@doingdev/opencode-claude-manager-plugin 0.1.65 → 0.1.66

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.
Files changed (123) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/manager/team-orchestrator.js +1 -1
  3. package/dist/plugin/agents/common.d.ts +2 -2
  4. package/dist/plugin/agents/common.js +5 -0
  5. package/dist/plugin/claude-manager.plugin.js +104 -0
  6. package/dist/plugin/inbox-ops.d.ts +50 -0
  7. package/dist/plugin/inbox-ops.js +166 -0
  8. package/dist/types/contracts.d.ts +18 -0
  9. package/package.json +1 -1
  10. package/dist/claude/session-live-tailer.d.ts +0 -51
  11. package/dist/claude/session-live-tailer.js +0 -269
  12. package/dist/manager/session-controller.d.ts +0 -41
  13. package/dist/manager/session-controller.js +0 -97
  14. package/dist/metadata/claude-metadata.service.d.ts +0 -12
  15. package/dist/metadata/claude-metadata.service.js +0 -38
  16. package/dist/metadata/repo-claude-config-reader.d.ts +0 -7
  17. package/dist/metadata/repo-claude-config-reader.js +0 -154
  18. package/dist/plugin/orchestrator.plugin.d.ts +0 -2
  19. package/dist/plugin/orchestrator.plugin.js +0 -116
  20. package/dist/providers/claude-code-wrapper.d.ts +0 -13
  21. package/dist/providers/claude-code-wrapper.js +0 -13
  22. package/dist/safety/bash-safety.d.ts +0 -21
  23. package/dist/safety/bash-safety.js +0 -62
  24. package/dist/src/claude/claude-agent-sdk-adapter.d.ts +0 -28
  25. package/dist/src/claude/claude-agent-sdk-adapter.js +0 -559
  26. package/dist/src/claude/claude-session.service.d.ts +0 -9
  27. package/dist/src/claude/claude-session.service.js +0 -15
  28. package/dist/src/claude/session-live-tailer.d.ts +0 -51
  29. package/dist/src/claude/session-live-tailer.js +0 -269
  30. package/dist/src/claude/tool-approval-manager.d.ts +0 -30
  31. package/dist/src/claude/tool-approval-manager.js +0 -279
  32. package/dist/src/index.d.ts +0 -5
  33. package/dist/src/index.js +0 -3
  34. package/dist/src/manager/context-tracker.d.ts +0 -32
  35. package/dist/src/manager/context-tracker.js +0 -103
  36. package/dist/src/manager/git-operations.d.ts +0 -18
  37. package/dist/src/manager/git-operations.js +0 -86
  38. package/dist/src/manager/persistent-manager.d.ts +0 -39
  39. package/dist/src/manager/persistent-manager.js +0 -44
  40. package/dist/src/manager/session-controller.d.ts +0 -41
  41. package/dist/src/manager/session-controller.js +0 -97
  42. package/dist/src/manager/team-orchestrator.d.ts +0 -81
  43. package/dist/src/manager/team-orchestrator.js +0 -612
  44. package/dist/src/plugin/agent-hierarchy.d.ts +0 -1
  45. package/dist/src/plugin/agent-hierarchy.js +0 -2
  46. package/dist/src/plugin/agents/browser-qa.d.ts +0 -14
  47. package/dist/src/plugin/agents/browser-qa.js +0 -31
  48. package/dist/src/plugin/agents/common.d.ts +0 -36
  49. package/dist/src/plugin/agents/common.js +0 -59
  50. package/dist/src/plugin/agents/cto.d.ts +0 -9
  51. package/dist/src/plugin/agents/cto.js +0 -39
  52. package/dist/src/plugin/agents/engineers.d.ts +0 -9
  53. package/dist/src/plugin/agents/engineers.js +0 -11
  54. package/dist/src/plugin/agents/index.d.ts +0 -5
  55. package/dist/src/plugin/agents/index.js +0 -5
  56. package/dist/src/plugin/agents/team-planner.d.ts +0 -10
  57. package/dist/src/plugin/agents/team-planner.js +0 -23
  58. package/dist/src/plugin/claude-manager.plugin.d.ts +0 -10
  59. package/dist/src/plugin/claude-manager.plugin.js +0 -950
  60. package/dist/src/plugin/service-factory.d.ts +0 -38
  61. package/dist/src/plugin/service-factory.js +0 -101
  62. package/dist/src/prompts/registry.d.ts +0 -2
  63. package/dist/src/prompts/registry.js +0 -210
  64. package/dist/src/state/file-run-state-store.d.ts +0 -14
  65. package/dist/src/state/file-run-state-store.js +0 -85
  66. package/dist/src/state/team-state-store.d.ts +0 -14
  67. package/dist/src/state/team-state-store.js +0 -88
  68. package/dist/src/state/transcript-store.d.ts +0 -15
  69. package/dist/src/state/transcript-store.js +0 -44
  70. package/dist/src/team/roster.d.ts +0 -5
  71. package/dist/src/team/roster.js +0 -40
  72. package/dist/src/types/contracts.d.ts +0 -261
  73. package/dist/src/types/contracts.js +0 -2
  74. package/dist/src/util/fs-helpers.d.ts +0 -8
  75. package/dist/src/util/fs-helpers.js +0 -21
  76. package/dist/src/util/project-context.d.ts +0 -10
  77. package/dist/src/util/project-context.js +0 -105
  78. package/dist/src/util/transcript-append.d.ts +0 -7
  79. package/dist/src/util/transcript-append.js +0 -29
  80. package/dist/state/file-run-state-store.d.ts +0 -14
  81. package/dist/state/file-run-state-store.js +0 -85
  82. package/dist/test/claude-agent-sdk-adapter.test.d.ts +0 -1
  83. package/dist/test/claude-agent-sdk-adapter.test.js +0 -707
  84. package/dist/test/claude-manager.plugin.test.d.ts +0 -1
  85. package/dist/test/claude-manager.plugin.test.js +0 -316
  86. package/dist/test/context-tracker.test.d.ts +0 -1
  87. package/dist/test/context-tracker.test.js +0 -130
  88. package/dist/test/cto-active-team.test.d.ts +0 -1
  89. package/dist/test/cto-active-team.test.js +0 -199
  90. package/dist/test/file-run-state-store.test.d.ts +0 -1
  91. package/dist/test/file-run-state-store.test.js +0 -82
  92. package/dist/test/fs-helpers.test.d.ts +0 -1
  93. package/dist/test/fs-helpers.test.js +0 -56
  94. package/dist/test/git-operations.test.d.ts +0 -1
  95. package/dist/test/git-operations.test.js +0 -133
  96. package/dist/test/persistent-manager.test.d.ts +0 -1
  97. package/dist/test/persistent-manager.test.js +0 -48
  98. package/dist/test/project-context.test.d.ts +0 -1
  99. package/dist/test/project-context.test.js +0 -92
  100. package/dist/test/prompt-registry.test.d.ts +0 -1
  101. package/dist/test/prompt-registry.test.js +0 -117
  102. package/dist/test/report-claude-event.test.d.ts +0 -1
  103. package/dist/test/report-claude-event.test.js +0 -304
  104. package/dist/test/session-controller.test.d.ts +0 -1
  105. package/dist/test/session-controller.test.js +0 -149
  106. package/dist/test/session-live-tailer.test.d.ts +0 -1
  107. package/dist/test/session-live-tailer.test.js +0 -313
  108. package/dist/test/team-orchestrator.test.d.ts +0 -1
  109. package/dist/test/team-orchestrator.test.js +0 -583
  110. package/dist/test/team-state-store.test.d.ts +0 -1
  111. package/dist/test/team-state-store.test.js +0 -54
  112. package/dist/test/tool-approval-manager.test.d.ts +0 -1
  113. package/dist/test/tool-approval-manager.test.js +0 -260
  114. package/dist/test/transcript-append.test.d.ts +0 -1
  115. package/dist/test/transcript-append.test.js +0 -37
  116. package/dist/test/transcript-store.test.d.ts +0 -1
  117. package/dist/test/transcript-store.test.js +0 -50
  118. package/dist/test/undo-propagation.test.d.ts +0 -1
  119. package/dist/test/undo-propagation.test.js +0 -837
  120. package/dist/util/project-context.d.ts +0 -10
  121. package/dist/util/project-context.js +0 -105
  122. package/dist/vitest.config.d.ts +0 -2
  123. package/dist/vitest.config.js +0 -11
@@ -1,269 +0,0 @@
1
- import { createReadStream, existsSync, readdirSync, statSync } from 'node:fs';
2
- import { createInterface } from 'node:readline';
3
- import path from 'node:path';
4
- import os from 'node:os';
5
- /**
6
- * Tails Claude Code session JSONL files for live tool output.
7
- *
8
- * The SDK streams high-level events (assistant text, tool_call summaries, results)
9
- * but does not expose the raw tool output that Claude Code writes to the JSONL
10
- * transcript on disk. This service fills that gap by polling the file for new
11
- * lines, parsing each one, and forwarding parsed events to a caller-supplied
12
- * callback.
13
- */
14
- export class SessionLiveTailer {
15
- activeTails = new Map();
16
- // ── Path discovery ──────────────────────────────────────────────────
17
- /**
18
- * Locate the JSONL file for a session.
19
- *
20
- * Claude Code stores transcripts at:
21
- * ~/.claude/projects/<sanitized-cwd>/sessions/<session-id>.jsonl
22
- *
23
- * The `<sanitized-cwd>` folder name is an internal implementation detail that
24
- * can change across Claude Code versions, so we search all project directories
25
- * for the session file rather than attempting to replicate the sanitisation.
26
- */
27
- findSessionFile(sessionId, cwd) {
28
- const projectsDir = path.join(os.homedir(), '.claude', 'projects');
29
- if (!existsSync(projectsDir)) {
30
- return null;
31
- }
32
- // If cwd is provided, try the sanitised form first (best-effort fast path).
33
- if (cwd) {
34
- const sanitised = cwd.replace(/\//g, '-');
35
- const candidate = path.join(projectsDir, sanitised, 'sessions', `${sessionId}.jsonl`);
36
- if (existsSync(candidate)) {
37
- return candidate;
38
- }
39
- }
40
- // Fall back to scanning all project directories.
41
- try {
42
- for (const entry of readdirSync(projectsDir, { withFileTypes: true })) {
43
- if (!entry.isDirectory())
44
- continue;
45
- const candidate = path.join(projectsDir, entry.name, 'sessions', `${sessionId}.jsonl`);
46
- if (existsSync(candidate)) {
47
- return candidate;
48
- }
49
- }
50
- }
51
- catch {
52
- // Permission denied or similar — nothing we can do.
53
- }
54
- return null;
55
- }
56
- /**
57
- * Check whether we can locate a JSONL file for the given session.
58
- */
59
- sessionFileExists(sessionId, cwd) {
60
- return this.findSessionFile(sessionId, cwd) !== null;
61
- }
62
- // ── Live tailing ────────────────────────────────────────────────────
63
- /**
64
- * Poll a session's JSONL file for new lines and emit parsed events.
65
- *
66
- * Returns a stop function. The caller **must** invoke it when tailing is no
67
- * longer needed (e.g. when the session completes or the tool is interrupted).
68
- */
69
- startTailing(sessionId, cwd, onEvent, pollIntervalMs = 150) {
70
- const filePath = this.findSessionFile(sessionId, cwd);
71
- if (!filePath) {
72
- onEvent({
73
- type: 'error',
74
- sessionId,
75
- error: `Session JSONL not found for ${sessionId}`,
76
- });
77
- return () => { };
78
- }
79
- let offset = statSync(filePath).size;
80
- let buffer = '';
81
- let reading = false; // guard against overlapping reads
82
- const interval = setInterval(() => {
83
- if (reading)
84
- return;
85
- try {
86
- const currentSize = statSync(filePath).size;
87
- if (currentSize < offset) {
88
- // File was truncated (rotation / compaction) — reset.
89
- offset = 0;
90
- buffer = '';
91
- }
92
- if (currentSize <= offset)
93
- return;
94
- reading = true;
95
- const stream = createReadStream(filePath, {
96
- start: offset,
97
- end: currentSize - 1,
98
- encoding: 'utf8',
99
- });
100
- let chunk = '';
101
- stream.on('data', (data) => {
102
- chunk += typeof data === 'string' ? data : data.toString('utf8');
103
- });
104
- stream.on('end', () => {
105
- reading = false;
106
- offset = currentSize;
107
- buffer += chunk;
108
- const lines = buffer.split('\n');
109
- // Keep the last (possibly incomplete) segment in the buffer.
110
- buffer = lines.pop() ?? '';
111
- for (const line of lines) {
112
- const trimmed = line.trim();
113
- if (!trimmed)
114
- continue;
115
- try {
116
- const parsed = JSON.parse(trimmed);
117
- onEvent({
118
- type: 'line',
119
- sessionId,
120
- data: parsed,
121
- rawLine: trimmed,
122
- });
123
- }
124
- catch {
125
- onEvent({
126
- type: 'line',
127
- sessionId,
128
- data: null,
129
- rawLine: trimmed,
130
- });
131
- }
132
- }
133
- });
134
- stream.on('error', (err) => {
135
- reading = false;
136
- onEvent({
137
- type: 'error',
138
- sessionId,
139
- error: err.message,
140
- });
141
- });
142
- }
143
- catch (err) {
144
- reading = false;
145
- onEvent({
146
- type: 'error',
147
- sessionId,
148
- error: err instanceof Error ? err.message : String(err),
149
- });
150
- }
151
- }, pollIntervalMs);
152
- this.activeTails.set(sessionId, interval);
153
- return () => this.stopTailing(sessionId);
154
- }
155
- /**
156
- * Stop tailing a specific session.
157
- */
158
- stopTailing(sessionId) {
159
- const interval = this.activeTails.get(sessionId);
160
- if (interval) {
161
- clearInterval(interval);
162
- this.activeTails.delete(sessionId);
163
- }
164
- }
165
- /**
166
- * Stop all active tails (cleanup on shutdown).
167
- */
168
- stopAll() {
169
- for (const [, interval] of this.activeTails) {
170
- clearInterval(interval);
171
- }
172
- this.activeTails.clear();
173
- }
174
- // ── Snapshot helpers ────────────────────────────────────────────────
175
- /**
176
- * Read the last N lines from a session JSONL file.
177
- */
178
- async getLastLines(sessionId, cwd, lineCount = 20) {
179
- const filePath = this.findSessionFile(sessionId, cwd);
180
- if (!filePath)
181
- return [];
182
- const lines = [];
183
- const rl = createInterface({
184
- input: createReadStream(filePath, { encoding: 'utf8' }),
185
- });
186
- for await (const line of rl) {
187
- lines.push(line);
188
- if (lines.length > lineCount) {
189
- lines.shift();
190
- }
191
- }
192
- return lines;
193
- }
194
- /**
195
- * Extract a preview of recent tool output from the tail of a session file.
196
- */
197
- async getToolOutputPreview(sessionId, cwd, maxEntries = 5) {
198
- const lastLines = await this.getLastLines(sessionId, cwd, 100);
199
- const previews = [];
200
- for (const line of lastLines) {
201
- const trimmed = line.trim();
202
- if (!trimmed)
203
- continue;
204
- try {
205
- const parsed = JSON.parse(trimmed);
206
- const preview = extractToolOutput(parsed);
207
- if (preview) {
208
- previews.push(preview);
209
- }
210
- }
211
- catch {
212
- // skip unparseable lines
213
- }
214
- }
215
- return previews.slice(-maxEntries);
216
- }
217
- }
218
- // ── Internal helpers ────────────────────────────────────────────────────
219
- /**
220
- * Attempt to extract tool output information from a JSONL record.
221
- *
222
- * Claude Code JSONL records with tool results can appear as:
223
- * 1. A top-level `{ type: "user", message: { content: [{ type: "tool_result", ... }] } }`
224
- * 2. Direct `tool_result` entries (less common).
225
- */
226
- function extractToolOutput(record) {
227
- // Pattern 1: user message wrapping tool_result content blocks
228
- if (record.type === 'user') {
229
- const message = record.message;
230
- if (!message)
231
- return null;
232
- const content = message.content;
233
- if (!Array.isArray(content))
234
- return null;
235
- for (const block of content) {
236
- if (block &&
237
- typeof block === 'object' &&
238
- block.type === 'tool_result') {
239
- const b = block;
240
- return {
241
- toolUseId: typeof b.tool_use_id === 'string' ? b.tool_use_id : '',
242
- content: stringifyContent(b.content),
243
- isError: b.is_error === true,
244
- };
245
- }
246
- }
247
- }
248
- // Pattern 2: direct tool_result record (varies by Claude Code version)
249
- if (record.type === 'tool_result') {
250
- return {
251
- toolUseId: typeof record.tool_use_id === 'string' ? record.tool_use_id : '',
252
- content: stringifyContent(record.content),
253
- isError: record.is_error === true,
254
- };
255
- }
256
- return null;
257
- }
258
- function stringifyContent(value) {
259
- if (typeof value === 'string')
260
- return value;
261
- if (value === undefined || value === null)
262
- return '';
263
- try {
264
- return JSON.stringify(value);
265
- }
266
- catch {
267
- return '[non-serializable]';
268
- }
269
- }
@@ -1,30 +0,0 @@
1
- import type { ToolApprovalDecision, ToolApprovalPolicy, ToolApprovalRule } from '../types/contracts.js';
2
- export declare class ToolApprovalManager {
3
- private policy;
4
- private decisions;
5
- private readonly maxDecisions;
6
- private readonly persistPath;
7
- constructor(policy?: Partial<ToolApprovalPolicy>, maxDecisions?: number, persistPath?: string);
8
- loadPersistedPolicy(): Promise<void>;
9
- private persistPolicy;
10
- evaluate(toolName: string, input: Record<string, unknown>, options?: {
11
- title?: string;
12
- agentID?: string;
13
- }): {
14
- behavior: 'allow';
15
- } | {
16
- behavior: 'deny';
17
- message: string;
18
- };
19
- getDecisions(limit?: number): ToolApprovalDecision[];
20
- getDeniedDecisions(limit?: number): ToolApprovalDecision[];
21
- clearDecisions(): void;
22
- getPolicy(): ToolApprovalPolicy;
23
- setPolicy(policy: ToolApprovalPolicy): Promise<void>;
24
- addRule(rule: ToolApprovalRule, position?: number): Promise<void>;
25
- removeRule(ruleId: string): Promise<boolean>;
26
- setDefaultAction(action: 'allow' | 'deny'): Promise<void>;
27
- setEnabled(enabled: boolean): Promise<void>;
28
- private findMatchingRule;
29
- private recordDecision;
30
- }
@@ -1,279 +0,0 @@
1
- import { promises as fs } from 'node:fs';
2
- import path from 'node:path';
3
- import { isFileNotFoundError, writeJsonAtomically } from '../util/fs-helpers.js';
4
- const DEFAULT_MAX_DECISIONS = 500;
5
- const INPUT_PREVIEW_MAX = 300;
6
- function normalizePolicy(policy) {
7
- return {
8
- ...policy,
9
- rules: [...policy.rules],
10
- defaultAction: 'allow',
11
- };
12
- }
13
- function getDefaultRules() {
14
- return [
15
- // Safe read-only tools
16
- {
17
- id: 'allow-read',
18
- toolPattern: 'Read',
19
- action: 'allow',
20
- description: 'Allow reading files',
21
- },
22
- {
23
- id: 'allow-grep',
24
- toolPattern: 'Grep',
25
- action: 'allow',
26
- description: 'Allow grep searches',
27
- },
28
- {
29
- id: 'allow-glob',
30
- toolPattern: 'Glob',
31
- action: 'allow',
32
- description: 'Allow glob file searches',
33
- },
34
- {
35
- id: 'allow-ls',
36
- toolPattern: 'LS',
37
- action: 'allow',
38
- description: 'Allow directory listing',
39
- },
40
- {
41
- id: 'allow-list',
42
- toolPattern: 'ListDirectory',
43
- action: 'allow',
44
- description: 'Allow listing directories',
45
- },
46
- // Edit tools
47
- {
48
- id: 'allow-edit',
49
- toolPattern: 'Edit',
50
- action: 'allow',
51
- description: 'Allow file edits',
52
- },
53
- {
54
- id: 'allow-multiedit',
55
- toolPattern: 'MultiEdit',
56
- action: 'allow',
57
- description: 'Allow multi-edits',
58
- },
59
- {
60
- id: 'allow-write',
61
- toolPattern: 'Write',
62
- action: 'allow',
63
- description: 'Allow file writes',
64
- },
65
- {
66
- id: 'allow-notebook',
67
- toolPattern: 'NotebookEdit',
68
- action: 'allow',
69
- description: 'Allow notebook edits',
70
- },
71
- // Bash - deny dangerous patterns first, then allow the rest
72
- {
73
- id: 'deny-bash-rm-rf-root',
74
- toolPattern: 'Bash',
75
- inputPattern: 'rm -rf /',
76
- action: 'deny',
77
- denyMessage: 'Destructive rm -rf on root path is not allowed.',
78
- description: 'Block rm -rf on root',
79
- },
80
- {
81
- id: 'deny-bash-force-push',
82
- toolPattern: 'Bash',
83
- inputPattern: 'git push --force',
84
- action: 'deny',
85
- denyMessage: 'Force push is not allowed.',
86
- description: 'Block git force push',
87
- },
88
- {
89
- id: 'deny-bash-reset-hard',
90
- toolPattern: 'Bash',
91
- inputPattern: 'git reset --hard',
92
- action: 'deny',
93
- denyMessage: 'git reset --hard is not allowed from Claude Code. Use the manager git_reset tool instead.',
94
- description: 'Block git reset --hard',
95
- },
96
- {
97
- id: 'allow-bash',
98
- toolPattern: 'Bash',
99
- action: 'allow',
100
- description: 'Allow bash commands (after dangerous patterns filtered)',
101
- },
102
- // Agent / misc
103
- {
104
- id: 'allow-skill',
105
- toolPattern: 'Skill',
106
- action: 'allow',
107
- description: 'Allow Agent Skills (filesystem SKILL.md)',
108
- },
109
- {
110
- id: 'allow-agent',
111
- toolPattern: 'Agent',
112
- action: 'allow',
113
- description: 'Allow agent delegation',
114
- },
115
- {
116
- id: 'allow-todowrite',
117
- toolPattern: 'TodoWrite',
118
- action: 'allow',
119
- description: 'Allow todo tracking',
120
- },
121
- {
122
- id: 'allow-todoread',
123
- toolPattern: 'TodoRead',
124
- action: 'allow',
125
- description: 'Allow todo reading',
126
- },
127
- ];
128
- }
129
- export class ToolApprovalManager {
130
- policy;
131
- decisions = [];
132
- maxDecisions;
133
- persistPath;
134
- constructor(policy, maxDecisions, persistPath) {
135
- this.policy = normalizePolicy({
136
- rules: policy?.rules ?? getDefaultRules(),
137
- defaultAction: 'allow',
138
- defaultDenyMessage: policy?.defaultDenyMessage ?? 'Tool call denied by approval policy.',
139
- enabled: policy?.enabled ?? true,
140
- });
141
- this.maxDecisions = maxDecisions ?? DEFAULT_MAX_DECISIONS;
142
- this.persistPath = persistPath ?? null;
143
- }
144
- async loadPersistedPolicy() {
145
- if (!this.persistPath) {
146
- return;
147
- }
148
- try {
149
- const content = await fs.readFile(this.persistPath, 'utf8');
150
- const loaded = JSON.parse(content);
151
- this.policy = normalizePolicy({
152
- rules: loaded.rules ?? getDefaultRules(),
153
- defaultAction: 'allow',
154
- defaultDenyMessage: loaded.defaultDenyMessage ?? 'Tool call denied by approval policy.',
155
- enabled: loaded.enabled ?? true,
156
- });
157
- }
158
- catch (error) {
159
- if (!isFileNotFoundError(error)) {
160
- throw error;
161
- }
162
- }
163
- }
164
- async persistPolicy() {
165
- if (!this.persistPath) {
166
- return;
167
- }
168
- await fs.mkdir(path.dirname(this.persistPath), { recursive: true });
169
- await writeJsonAtomically(this.persistPath, this.policy);
170
- }
171
- evaluate(toolName, input, options) {
172
- if (!this.policy.enabled) {
173
- return { behavior: 'allow' };
174
- }
175
- const inputJson = safeJsonStringify(input);
176
- const matchedRule = this.findMatchingRule(toolName, inputJson);
177
- const action = matchedRule?.action ?? 'allow';
178
- const denyMessage = action === 'deny'
179
- ? (matchedRule?.denyMessage ?? this.policy.defaultDenyMessage ?? 'Denied by policy.')
180
- : undefined;
181
- this.recordDecision({
182
- timestamp: new Date().toISOString(),
183
- toolName,
184
- inputPreview: inputJson.slice(0, INPUT_PREVIEW_MAX),
185
- title: options?.title,
186
- matchedRuleId: matchedRule?.id ?? 'default',
187
- action,
188
- denyMessage,
189
- agentId: options?.agentID,
190
- });
191
- if (action === 'deny') {
192
- return { behavior: 'deny', message: denyMessage };
193
- }
194
- return { behavior: 'allow' };
195
- }
196
- getDecisions(limit) {
197
- const all = [...this.decisions].reverse();
198
- return limit ? all.slice(0, limit) : all;
199
- }
200
- getDeniedDecisions(limit) {
201
- const denied = this.decisions.filter((d) => d.action === 'deny').reverse();
202
- return limit ? denied.slice(0, limit) : denied;
203
- }
204
- clearDecisions() {
205
- this.decisions = [];
206
- }
207
- getPolicy() {
208
- return { ...this.policy, rules: [...this.policy.rules] };
209
- }
210
- async setPolicy(policy) {
211
- this.policy = normalizePolicy(policy);
212
- await this.persistPolicy();
213
- }
214
- async addRule(rule, position) {
215
- if (position !== undefined && position >= 0 && position < this.policy.rules.length) {
216
- this.policy.rules.splice(position, 0, rule);
217
- }
218
- else {
219
- this.policy.rules.push(rule);
220
- }
221
- await this.persistPolicy();
222
- }
223
- async removeRule(ruleId) {
224
- const index = this.policy.rules.findIndex((r) => r.id === ruleId);
225
- if (index === -1) {
226
- return false;
227
- }
228
- this.policy.rules.splice(index, 1);
229
- await this.persistPolicy();
230
- return true;
231
- }
232
- async setDefaultAction(action) {
233
- if (action === 'deny') {
234
- throw new Error('defaultAction cannot be deny; unmatched tools are always allowed. Add explicit deny rules instead.');
235
- }
236
- this.policy = normalizePolicy(this.policy);
237
- await this.persistPolicy();
238
- }
239
- async setEnabled(enabled) {
240
- this.policy.enabled = enabled;
241
- await this.persistPolicy();
242
- }
243
- findMatchingRule(toolName, inputJson) {
244
- for (const rule of this.policy.rules) {
245
- if (!matchesToolPattern(rule.toolPattern, toolName)) {
246
- continue;
247
- }
248
- if (rule.inputPattern && !inputJson.includes(rule.inputPattern)) {
249
- continue;
250
- }
251
- return rule;
252
- }
253
- return null;
254
- }
255
- recordDecision(decision) {
256
- this.decisions.push(decision);
257
- if (this.decisions.length > this.maxDecisions) {
258
- this.decisions = this.decisions.slice(-this.maxDecisions);
259
- }
260
- }
261
- }
262
- function matchesToolPattern(pattern, toolName) {
263
- if (pattern === '*') {
264
- return true;
265
- }
266
- if (!pattern.includes('*')) {
267
- return pattern === toolName;
268
- }
269
- const regex = new RegExp('^' + pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$');
270
- return regex.test(toolName);
271
- }
272
- function safeJsonStringify(value) {
273
- try {
274
- return JSON.stringify(value);
275
- }
276
- catch {
277
- return String(value);
278
- }
279
- }
@@ -1,5 +0,0 @@
1
- import type { Plugin } from '@opencode-ai/plugin';
2
- import { ClaudeManagerPlugin } from './plugin/claude-manager.plugin.js';
3
- export type { ClaudeCapabilitySnapshot, ClaudeSessionRunResult, ClaudeSessionSummary, ClaudeSessionTranscriptMessage, ManagerPromptRegistry, RunClaudeSessionInput, SessionContextSnapshot, GitDiffResult, GitOperationResult, ContextWarningLevel, SessionMode, EngineerName, EngineerWorkMode, EngineerFailureKind, EngineerFailureResult, WrapperHistoryEntry, TeamEngineerRecord, TeamRecord, EngineerTaskResult, PlanDraft, SynthesizedPlanResult, ToolApprovalRule, ToolApprovalPolicy, ToolApprovalDecision, } from './types/contracts.js';
4
- export { ClaudeManagerPlugin };
5
- export declare const plugin: Plugin;
package/dist/src/index.js DELETED
@@ -1,3 +0,0 @@
1
- import { ClaudeManagerPlugin } from './plugin/claude-manager.plugin.js';
2
- export { ClaudeManagerPlugin };
3
- export const plugin = ClaudeManagerPlugin;
@@ -1,32 +0,0 @@
1
- import type { ContextWarningLevel, SessionContextSnapshot } from '../types/contracts.js';
2
- export declare class ContextTracker {
3
- private totalTurns;
4
- private totalCostUsd;
5
- private latestInputTokens;
6
- private latestOutputTokens;
7
- private contextWindowSize;
8
- private compactionCount;
9
- private sessionId;
10
- recordResult(result: {
11
- sessionId?: string;
12
- turns?: number;
13
- totalCostUsd?: number;
14
- inputTokens?: number;
15
- outputTokens?: number;
16
- contextWindowSize?: number;
17
- }): void;
18
- recordCompaction(): void;
19
- snapshot(): SessionContextSnapshot;
20
- warningLevel(): ContextWarningLevel;
21
- estimateContextPercent(): number | null;
22
- reset(): void;
23
- /** Restore from persisted active session state. */
24
- restore(state: {
25
- sessionId: string;
26
- totalTurns: number;
27
- totalCostUsd: number;
28
- estimatedContextPercent: number | null;
29
- contextWindowSize: number | null;
30
- latestInputTokens: number | null;
31
- }): void;
32
- }