@kodus/cli 0.1.12 → 0.2.1

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 (102) hide show
  1. package/README.md +293 -208
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +2 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/__tests__/auth.team-key.test.js +16 -0
  6. package/dist/commands/__tests__/auth.team-key.test.js.map +1 -1
  7. package/dist/commands/__tests__/capture-api.test.d.ts +2 -0
  8. package/dist/commands/__tests__/capture-api.test.d.ts.map +1 -0
  9. package/dist/commands/__tests__/capture-api.test.js +88 -0
  10. package/dist/commands/__tests__/capture-api.test.js.map +1 -0
  11. package/dist/commands/__tests__/disable.test.d.ts +2 -0
  12. package/dist/commands/__tests__/disable.test.d.ts.map +1 -0
  13. package/dist/commands/__tests__/disable.test.js +103 -0
  14. package/dist/commands/__tests__/disable.test.js.map +1 -0
  15. package/dist/commands/__tests__/enable.test.d.ts +2 -0
  16. package/dist/commands/__tests__/enable.test.d.ts.map +1 -0
  17. package/dist/commands/__tests__/enable.test.js +103 -0
  18. package/dist/commands/__tests__/enable.test.js.map +1 -0
  19. package/dist/commands/__tests__/install-merge-hook.test.d.ts +2 -0
  20. package/dist/commands/__tests__/install-merge-hook.test.d.ts.map +1 -0
  21. package/dist/commands/__tests__/install-merge-hook.test.js +54 -0
  22. package/dist/commands/__tests__/install-merge-hook.test.js.map +1 -0
  23. package/dist/commands/auth/team-key.d.ts.map +1 -1
  24. package/dist/commands/auth/team-key.js +1 -1
  25. package/dist/commands/auth/team-key.js.map +1 -1
  26. package/dist/commands/memory/capture.d.ts +8 -0
  27. package/dist/commands/memory/capture.d.ts.map +1 -0
  28. package/dist/commands/memory/capture.js +173 -0
  29. package/dist/commands/memory/capture.js.map +1 -0
  30. package/dist/commands/memory/disable.d.ts +2 -0
  31. package/dist/commands/memory/disable.d.ts.map +1 -0
  32. package/dist/commands/memory/disable.js +20 -0
  33. package/dist/commands/memory/disable.js.map +1 -0
  34. package/dist/commands/memory/enable.d.ts +8 -0
  35. package/dist/commands/memory/enable.d.ts.map +1 -0
  36. package/dist/commands/memory/enable.js +81 -0
  37. package/dist/commands/memory/enable.js.map +1 -0
  38. package/dist/commands/memory/hooks.d.ts +45 -0
  39. package/dist/commands/memory/hooks.d.ts.map +1 -0
  40. package/dist/commands/memory/hooks.js +347 -0
  41. package/dist/commands/memory/hooks.js.map +1 -0
  42. package/dist/commands/memory/index.d.ts +3 -0
  43. package/dist/commands/memory/index.d.ts.map +1 -0
  44. package/dist/commands/memory/index.js +44 -0
  45. package/dist/commands/memory/index.js.map +1 -0
  46. package/dist/commands/memory/promote.d.ts +7 -0
  47. package/dist/commands/memory/promote.d.ts.map +1 -0
  48. package/dist/commands/memory/promote.js +38 -0
  49. package/dist/commands/memory/promote.js.map +1 -0
  50. package/dist/commands/memory/show.d.ts +2 -0
  51. package/dist/commands/memory/show.d.ts.map +1 -0
  52. package/dist/commands/memory/show.js +44 -0
  53. package/dist/commands/memory/show.js.map +1 -0
  54. package/dist/commands/memory/status.d.ts +2 -0
  55. package/dist/commands/memory/status.d.ts.map +1 -0
  56. package/dist/commands/memory/status.js +54 -0
  57. package/dist/commands/memory/status.js.map +1 -0
  58. package/dist/services/__tests__/memory.service.test.d.ts +2 -0
  59. package/dist/services/__tests__/memory.service.test.d.ts.map +1 -0
  60. package/dist/services/__tests__/memory.service.test.js +279 -0
  61. package/dist/services/__tests__/memory.service.test.js.map +1 -0
  62. package/dist/services/__tests__/transcript-parser.service.test.d.ts +2 -0
  63. package/dist/services/__tests__/transcript-parser.service.test.d.ts.map +1 -0
  64. package/dist/services/__tests__/transcript-parser.service.test.js +134 -0
  65. package/dist/services/__tests__/transcript-parser.service.test.js.map +1 -0
  66. package/dist/services/api/__tests__/api.real.test.js +11 -0
  67. package/dist/services/api/__tests__/api.real.test.js.map +1 -1
  68. package/dist/services/api/api.interface.d.ts +5 -1
  69. package/dist/services/api/api.interface.d.ts.map +1 -1
  70. package/dist/services/api/api.real.d.ts +2 -1
  71. package/dist/services/api/api.real.d.ts.map +1 -1
  72. package/dist/services/api/api.real.js +15 -1
  73. package/dist/services/api/api.real.js.map +1 -1
  74. package/dist/services/api/index.d.ts +1 -1
  75. package/dist/services/api/index.d.ts.map +1 -1
  76. package/dist/services/git.service.d.ts +1 -0
  77. package/dist/services/git.service.d.ts.map +1 -1
  78. package/dist/services/git.service.js +9 -0
  79. package/dist/services/git.service.js.map +1 -1
  80. package/dist/services/memory.service.d.ts +49 -0
  81. package/dist/services/memory.service.d.ts.map +1 -0
  82. package/dist/services/memory.service.js +450 -0
  83. package/dist/services/memory.service.js.map +1 -0
  84. package/dist/services/transcript-parser.service.d.ts +10 -0
  85. package/dist/services/transcript-parser.service.d.ts.map +1 -0
  86. package/dist/services/transcript-parser.service.js +96 -0
  87. package/dist/services/transcript-parser.service.js.map +1 -0
  88. package/dist/types/index.d.ts +1 -0
  89. package/dist/types/index.d.ts.map +1 -1
  90. package/dist/types/memory.d.ts +85 -0
  91. package/dist/types/memory.d.ts.map +1 -0
  92. package/dist/types/memory.js +2 -0
  93. package/dist/types/memory.js.map +1 -0
  94. package/dist/utils/__tests__/module-matcher.test.d.ts +2 -0
  95. package/dist/utils/__tests__/module-matcher.test.d.ts.map +1 -0
  96. package/dist/utils/__tests__/module-matcher.test.js +164 -0
  97. package/dist/utils/__tests__/module-matcher.test.js.map +1 -0
  98. package/dist/utils/module-matcher.d.ts +6 -0
  99. package/dist/utils/module-matcher.d.ts.map +1 -0
  100. package/dist/utils/module-matcher.js +94 -0
  101. package/dist/utils/module-matcher.js.map +1 -0
  102. package/package.json +3 -2
@@ -0,0 +1,173 @@
1
+ import chalk from 'chalk';
2
+ import { gitService } from '../../services/git.service.js';
3
+ import { authService } from '../../services/auth.service.js';
4
+ import { api } from '../../services/api/index.js';
5
+ import { memoryService } from '../../services/memory.service.js';
6
+ import { transcriptParserService } from '../../services/transcript-parser.service.js';
7
+ export async function captureAction(payloadArg, options) {
8
+ try {
9
+ const isRepo = await gitService.isGitRepository();
10
+ if (!isRepo) {
11
+ // Hook command must fail-open outside git repos.
12
+ return;
13
+ }
14
+ const repoRoot = (await gitService.getGitRoot()).trim();
15
+ const headSha = await gitService.getHeadSha();
16
+ const payloadFromStdin = payloadArg ? undefined : await readStdinIfAvailable();
17
+ const rawPayload = selectRawPayload(payloadFromStdin, payloadArg);
18
+ const parsedPayload = parsePayload(rawPayload);
19
+ const resolvedAgent = resolveAgent(options.agent);
20
+ // Resolve branch for new structured storage
21
+ let branch;
22
+ try {
23
+ branch = (await gitService.getCurrentBranch()).trim();
24
+ }
25
+ catch {
26
+ // Detached HEAD or no branch - fall back to legacy
27
+ }
28
+ if (branch) {
29
+ const signals = transcriptParserService.parse(parsedPayload);
30
+ const filePath = await memoryService.saveBranchCapture({
31
+ repoRoot,
32
+ headSha,
33
+ agent: resolvedAgent,
34
+ event: options.event,
35
+ branch,
36
+ payload: parsedPayload,
37
+ summary: options.summary,
38
+ }, signals);
39
+ if (process.env.KODUS_VERBOSE === 'true') {
40
+ console.log(chalk.dim(`[memory] saved branch capture to ${filePath}`));
41
+ }
42
+ if (options.event === 'stop') {
43
+ submitCaptureToApi({ repoRoot, headSha, branch, agent: resolvedAgent, event: options.event, signals, summary: options.summary })
44
+ .catch(() => { }); // Intentionally swallowed — must not block hook
45
+ }
46
+ }
47
+ else {
48
+ // Legacy per-SHA fallback
49
+ const filePath = await memoryService.saveCapture({
50
+ repoRoot,
51
+ headSha,
52
+ agent: resolvedAgent,
53
+ event: options.event,
54
+ payload: parsedPayload,
55
+ summary: options.summary,
56
+ });
57
+ if (process.env.KODUS_VERBOSE === 'true') {
58
+ console.log(chalk.dim(`[memory] saved capture to ${filePath}`));
59
+ }
60
+ }
61
+ }
62
+ catch (error) {
63
+ // Hooks should not block development flow.
64
+ if (process.env.KODUS_VERBOSE === 'true') {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ console.error(chalk.yellow(`[memory] capture skipped: ${message}`));
67
+ }
68
+ }
69
+ }
70
+ function resolveAgent(rawAgent) {
71
+ if (rawAgent !== 'claude-compatible') {
72
+ return rawAgent;
73
+ }
74
+ if (process.env.CURSOR_VERSION || process.env.CURSOR_PROJECT_DIR) {
75
+ return 'cursor';
76
+ }
77
+ return 'claude-code';
78
+ }
79
+ async function readStdinIfAvailable() {
80
+ if (process.stdin.isTTY) {
81
+ return undefined;
82
+ }
83
+ return new Promise((resolve, reject) => {
84
+ let data = '';
85
+ let settled = false;
86
+ const noDataTimer = setTimeout(() => {
87
+ // Some hook runners keep stdin open forever without sending payload.
88
+ // In that case, fail open and continue without stdin payload.
89
+ finish(undefined);
90
+ }, 750);
91
+ const brokenStreamTimer = setTimeout(() => {
92
+ // Safety net for broken streams that emit data but never close.
93
+ finish(data.length > 0 ? data : undefined);
94
+ }, 5000);
95
+ const finish = (value) => {
96
+ if (settled)
97
+ return;
98
+ settled = true;
99
+ clearTimeout(noDataTimer);
100
+ clearTimeout(brokenStreamTimer);
101
+ process.stdin.removeAllListeners('data');
102
+ process.stdin.removeAllListeners('end');
103
+ process.stdin.removeAllListeners('error');
104
+ resolve(value ?? '');
105
+ };
106
+ process.stdin.setEncoding('utf-8');
107
+ process.stdin.on('data', (chunk) => {
108
+ data += chunk;
109
+ clearTimeout(noDataTimer);
110
+ });
111
+ process.stdin.on('end', () => {
112
+ finish(data);
113
+ });
114
+ process.stdin.on('error', (error) => {
115
+ clearTimeout(noDataTimer);
116
+ clearTimeout(brokenStreamTimer);
117
+ reject(error);
118
+ });
119
+ process.stdin.resume();
120
+ });
121
+ }
122
+ function parsePayload(rawPayload) {
123
+ if (!rawPayload) {
124
+ return undefined;
125
+ }
126
+ try {
127
+ return JSON.parse(rawPayload);
128
+ }
129
+ catch {
130
+ return { raw_payload: rawPayload };
131
+ }
132
+ }
133
+ function selectRawPayload(payloadFromStdin, payloadArg) {
134
+ const stdinValue = payloadFromStdin?.trim() ?? '';
135
+ if (stdinValue.length > 0) {
136
+ return stdinValue;
137
+ }
138
+ return (payloadArg ?? '').trim();
139
+ }
140
+ const ASSISTANT_MESSAGE_MAX_CHARS = 10_000;
141
+ async function submitCaptureToApi(params) {
142
+ const isAuthed = await authService.isAuthenticated();
143
+ if (!isAuthed)
144
+ return;
145
+ const token = await authService.getValidToken();
146
+ const orgRepoResult = await gitService.extractOrgRepo();
147
+ const orgRepo = orgRepoResult ? `${orgRepoResult.org}/${orgRepoResult.repo}` : null;
148
+ const truncatedAssistantMessage = params.signals.assistantMessage
149
+ ? params.signals.assistantMessage.slice(0, ASSISTANT_MESSAGE_MAX_CHARS)
150
+ : undefined;
151
+ const payload = {
152
+ branch: params.branch,
153
+ sha: params.headSha,
154
+ orgRepo,
155
+ agent: params.agent,
156
+ event: params.event,
157
+ signals: {
158
+ sessionId: params.signals.sessionId,
159
+ turnId: params.signals.turnId,
160
+ prompt: params.signals.prompt,
161
+ assistantMessage: truncatedAssistantMessage,
162
+ modifiedFiles: params.signals.modifiedFiles,
163
+ toolUses: params.signals.toolUses,
164
+ },
165
+ summary: params.summary,
166
+ capturedAt: new Date().toISOString(),
167
+ };
168
+ const result = await api.memory.submitCapture(payload, token);
169
+ if (process.env.KODUS_VERBOSE === 'true') {
170
+ console.log(chalk.dim(`[memory] submitted capture to API (id=${result.id}, accepted=${result.accepted})`));
171
+ }
172
+ }
173
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../../src/commands/memory/capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function disableAction(): Promise<void>;
2
+ //# sourceMappingURL=disable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disable.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/disable.ts"],"names":[],"mappings":"AASA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBnD"}
@@ -0,0 +1,20 @@
1
+ import chalk from 'chalk';
2
+ import { gitService } from '../../services/git.service.js';
3
+ import { removeClaudeCompatibleHooks, removeCodexNotify, removeMergeHook, resolveCodexConfigPath, } from './hooks.js';
4
+ export async function disableAction() {
5
+ const isRepo = await gitService.isGitRepository();
6
+ if (!isRepo) {
7
+ console.error(chalk.red('Error: Not a git repository.'));
8
+ process.exit(1);
9
+ }
10
+ const gitRoot = (await gitService.getGitRoot()).trim();
11
+ const claudeResult = await removeClaudeCompatibleHooks(gitRoot);
12
+ const codexResult = await removeCodexNotify(resolveCodexConfigPath());
13
+ const mergeResult = await removeMergeHook(gitRoot);
14
+ console.log(chalk.green('\u2713 Decision hooks removed.'));
15
+ console.log(` Claude Code / Cursor hooks: ${claudeResult.removed ? 'removed' : 'not found'}`);
16
+ console.log(` Codex notify: ${codexResult.removed ? 'removed' : 'not found'}`);
17
+ console.log(` Post-merge hook: ${mergeResult.removed ? 'removed' : 'not found'}`);
18
+ console.log(chalk.dim(' Memory data in .kody/ preserved.'));
19
+ }
20
+ //# sourceMappingURL=disable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disable.js","sourceRoot":"","sources":["../../../src/commands/memory/disable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,eAAe,EACf,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,eAAe,EAAE,CAAC;IAClD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAEvD,MAAM,YAAY,GAAG,MAAM,2BAA2B,CAAC,OAAO,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACtE,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAEnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,iCAAiC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,CAAC,mBAAmB,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,sBAAsB,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface EnableOptions {
2
+ agents?: string;
3
+ codexConfig?: string;
4
+ force?: boolean;
5
+ }
6
+ export declare function enableAction(options: EnableOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=enable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/enable.ts"],"names":[],"mappings":"AAeA,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiFxE"}
@@ -0,0 +1,81 @@
1
+ import chalk from 'chalk';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ import { gitService } from '../../services/git.service.js';
5
+ import { stringifyYaml } from '../../utils/module-matcher.js';
6
+ import { parseAgents, installClaudeCompatibleHooks, installCodexNotify, installMergeHook, resolveCodexConfigPath, detectModules, } from './hooks.js';
7
+ export async function enableAction(options) {
8
+ const isRepo = await gitService.isGitRepository();
9
+ if (!isRepo) {
10
+ console.error(chalk.red('Error: Not a git repository.'));
11
+ process.exit(1);
12
+ }
13
+ const gitRoot = (await gitService.getGitRoot()).trim();
14
+ let agents;
15
+ try {
16
+ agents = parseAgents(options.agents ?? 'claude,cursor,codex');
17
+ }
18
+ catch (error) {
19
+ console.error(chalk.red(error.message));
20
+ process.exit(1);
21
+ return;
22
+ }
23
+ const installClaudeCompat = agents.has('claude') || agents.has('cursor');
24
+ const installCodex = agents.has('codex');
25
+ // 1. Claude Code / Cursor hooks
26
+ let claudeStatus = 'skipped';
27
+ if (installClaudeCompat) {
28
+ const result = await installClaudeCompatibleHooks(gitRoot);
29
+ claudeStatus = result.changed ? 'installed' : 'already configured';
30
+ }
31
+ // 2. Codex notify
32
+ let codexStatus = 'skipped';
33
+ if (installCodex) {
34
+ const codexConfigPath = resolveCodexConfigPath(options.codexConfig);
35
+ const result = await installCodexNotify(codexConfigPath);
36
+ if (result.changed) {
37
+ codexStatus = 'installed';
38
+ }
39
+ else if (result.skipped) {
40
+ codexStatus = 'skipped (existing notify entry)';
41
+ }
42
+ else {
43
+ codexStatus = 'already configured';
44
+ }
45
+ }
46
+ // 3. Post-merge hook (always)
47
+ const mergeResult = await installMergeHook(gitRoot);
48
+ const mergeStatus = mergeResult.alreadyInstalled ? 'already configured' : 'installed';
49
+ // 4. Init modules.yml
50
+ const configPath = path.join(gitRoot, '.kody', 'modules.yml');
51
+ let modulesStatus;
52
+ let modulesExist = false;
53
+ try {
54
+ await fs.access(configPath);
55
+ modulesExist = true;
56
+ }
57
+ catch {
58
+ // doesn't exist
59
+ }
60
+ if (modulesExist && !options.force) {
61
+ modulesStatus = 'already exists';
62
+ }
63
+ else {
64
+ const srcPath = path.join(gitRoot, 'src');
65
+ const modules = await detectModules(srcPath);
66
+ const config = { version: 1, modules };
67
+ const yamlContent = stringifyYaml(config);
68
+ await fs.mkdir(path.dirname(configPath), { recursive: true });
69
+ await fs.writeFile(configPath, yamlContent, 'utf-8');
70
+ modulesStatus = modules.length > 0
71
+ ? `created (${modules.length} module${modules.length === 1 ? '' : 's'} detected)`
72
+ : 'created (no modules detected)';
73
+ }
74
+ // Summary
75
+ console.log(chalk.green('\u2713 Decisions enabled for this repository.'));
76
+ console.log(` Claude Code / Cursor hooks: ${claudeStatus}`);
77
+ console.log(` Codex notify: ${codexStatus}`);
78
+ console.log(` Post-merge hook: ${mergeStatus}`);
79
+ console.log(` Module config: ${modulesStatus}`);
80
+ }
81
+ //# sourceMappingURL=enable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable.js","sourceRoot":"","sources":["../../../src/commands/memory/enable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ export declare const SUPPORTED_AGENTS: Set<string>;
2
+ export declare const CLAUDE_CAPTURE_COMMANDS: {
3
+ userPromptSubmit: string;
4
+ stop: string;
5
+ postToolUseWrite: string;
6
+ postToolUseEdit: string;
7
+ };
8
+ export declare const CODEX_NOTIFY_LINE = "notify = [\"kodus\", \"decisions\", \"capture\", \"--agent\", \"codex\", \"--event\", \"stop\"]";
9
+ export declare const CODEX_NOTIFY_LINE_LEGACY = "notify = [\"kodus\", \"decisions\", \"capture\", \"--agent\", \"codex\", \"--event\", \"agent-turn-complete\"]";
10
+ export declare const MERGE_HOOK_MARKER = "# kodus-memory-post-merge";
11
+ export declare function parseAgents(rawAgents: string): Set<string>;
12
+ export declare function resolveCodexConfigPath(rawPath?: string): string;
13
+ export declare function installClaudeCompatibleHooks(repoRoot: string): Promise<{
14
+ settingsPath: string;
15
+ changed: boolean;
16
+ }>;
17
+ export declare function installCodexNotify(configPath: string): Promise<{
18
+ configPath: string;
19
+ changed: boolean;
20
+ skipped: boolean;
21
+ reason: string;
22
+ }>;
23
+ export declare function installMergeHook(gitRoot: string): Promise<{
24
+ hookPath: string;
25
+ alreadyInstalled: boolean;
26
+ }>;
27
+ export declare function detectModules(srcPath: string): Promise<Array<{
28
+ id: string;
29
+ name: string;
30
+ paths: string[];
31
+ memoryFile: string;
32
+ }>>;
33
+ export declare function removeClaudeCompatibleHooks(repoRoot: string): Promise<{
34
+ settingsPath: string;
35
+ removed: boolean;
36
+ }>;
37
+ export declare function removeCodexNotify(configPath: string): Promise<{
38
+ configPath: string;
39
+ removed: boolean;
40
+ }>;
41
+ export declare function removeMergeHook(gitRoot: string): Promise<{
42
+ hookPath: string;
43
+ removed: boolean;
44
+ }>;
45
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/hooks.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,gBAAgB,aAAyC,CAAC;AAIvE,eAAO,MAAM,uBAAuB;;;;;CAKnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,oGACuD,CAAC;AACtF,eAAO,MAAM,wBAAwB,mHAC+D,CAAC;AAErG,eAAO,MAAM,iBAAiB,8BAA8B,CAAC;AAuB7D,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAyB1D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAU/D;AAmGD,wBAAsB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAkBxH;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAwCD;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,CAAC,CA2BhH;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CActI;AAMD,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAkEvH;AAED,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAuB7G;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAuCtG"}