@hongmaple0820/scale-engine 0.1.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.
Files changed (78) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +64 -0
  3. package/dist/adapters/ClaudeCodeAdapter.d.ts +48 -0
  4. package/dist/adapters/ClaudeCodeAdapter.js +188 -0
  5. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -0
  6. package/dist/adapters/CodexAdapter.d.ts +14 -0
  7. package/dist/adapters/CodexAdapter.js +153 -0
  8. package/dist/adapters/CodexAdapter.js.map +1 -0
  9. package/dist/api/cli.d.ts +2 -0
  10. package/dist/api/cli.js +396 -0
  11. package/dist/api/cli.js.map +1 -0
  12. package/dist/api/doctor.d.ts +28 -0
  13. package/dist/api/doctor.js +182 -0
  14. package/dist/api/doctor.js.map +1 -0
  15. package/dist/api/mcp.d.ts +32 -0
  16. package/dist/api/mcp.js +227 -0
  17. package/dist/api/mcp.js.map +1 -0
  18. package/dist/artifact/fsm.d.ts +36 -0
  19. package/dist/artifact/fsm.js +199 -0
  20. package/dist/artifact/fsm.js.map +1 -0
  21. package/dist/artifact/fsmDefinitions.d.ts +18 -0
  22. package/dist/artifact/fsmDefinitions.js +243 -0
  23. package/dist/artifact/fsmDefinitions.js.map +1 -0
  24. package/dist/artifact/sqliteStore.d.ts +61 -0
  25. package/dist/artifact/sqliteStore.js +394 -0
  26. package/dist/artifact/sqliteStore.js.map +1 -0
  27. package/dist/artifact/store.d.ts +49 -0
  28. package/dist/artifact/store.js +118 -0
  29. package/dist/artifact/store.js.map +1 -0
  30. package/dist/artifact/types.d.ts +333 -0
  31. package/dist/artifact/types.js +50 -0
  32. package/dist/artifact/types.js.map +1 -0
  33. package/dist/context/ContextBuilder.d.ts +36 -0
  34. package/dist/context/ContextBuilder.js +53 -0
  35. package/dist/context/ContextBuilder.js.map +1 -0
  36. package/dist/core/container.d.ts +14 -0
  37. package/dist/core/container.js +33 -0
  38. package/dist/core/container.js.map +1 -0
  39. package/dist/core/eventBus.d.ts +60 -0
  40. package/dist/core/eventBus.js +158 -0
  41. package/dist/core/eventBus.js.map +1 -0
  42. package/dist/core/logger.d.ts +3 -0
  43. package/dist/core/logger.js +12 -0
  44. package/dist/core/logger.js.map +1 -0
  45. package/dist/evolution/BehaviorTracker.d.ts +38 -0
  46. package/dist/evolution/BehaviorTracker.js +52 -0
  47. package/dist/evolution/BehaviorTracker.js.map +1 -0
  48. package/dist/evolution/EvolutionEngine.d.ts +99 -0
  49. package/dist/evolution/EvolutionEngine.js +321 -0
  50. package/dist/evolution/EvolutionEngine.js.map +1 -0
  51. package/dist/guardrails/Gateway.d.ts +26 -0
  52. package/dist/guardrails/Gateway.js +57 -0
  53. package/dist/guardrails/Gateway.js.map +1 -0
  54. package/dist/guardrails/advancedDetectors.d.ts +26 -0
  55. package/dist/guardrails/advancedDetectors.js +138 -0
  56. package/dist/guardrails/advancedDetectors.js.map +1 -0
  57. package/dist/guardrails/detectors.d.ts +25 -0
  58. package/dist/guardrails/detectors.js +170 -0
  59. package/dist/guardrails/detectors.js.map +1 -0
  60. package/dist/guardrails/roles.d.ts +4 -0
  61. package/dist/guardrails/roles.js +54 -0
  62. package/dist/guardrails/roles.js.map +1 -0
  63. package/dist/index.d.ts +22 -0
  64. package/dist/index.js +22 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/knowledge/KnowledgeBase.d.ts +25 -0
  67. package/dist/knowledge/KnowledgeBase.js +81 -0
  68. package/dist/knowledge/KnowledgeBase.js.map +1 -0
  69. package/dist/orchestration/EffectsWiring.d.ts +8 -0
  70. package/dist/orchestration/EffectsWiring.js +87 -0
  71. package/dist/orchestration/EffectsWiring.js.map +1 -0
  72. package/dist/routing/ModelRouter.d.ts +30 -0
  73. package/dist/routing/ModelRouter.js +69 -0
  74. package/dist/routing/ModelRouter.js.map +1 -0
  75. package/dist/tasks/TaskEngine.d.ts +97 -0
  76. package/dist/tasks/TaskEngine.js +269 -0
  77. package/dist/tasks/TaskEngine.js.map +1 -0
  78. package/package.json +48 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SCALE Engine Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # SCALE Engine
2
+
3
+ > **S**caffold · **C**ontrol · **A**rtifact · **L**earn · **E**volve
4
+ >
5
+ > AI 工程化脚手架引擎 — 让 AI Agent 在物理约束下工作,而不是靠提示词自律。
6
+
7
+ [![Tests](https://img.shields.io/badge/tests-148%2B%20passed-brightgreen)]()
8
+ [![Node](https://img.shields.io/badge/node-%3E%3D20-blue)]()
9
+ [![License](https://img.shields.io/badge/license-MIT-green)]()
10
+
11
+ ## 核心理念
12
+
13
+ ```
14
+ 提示词说 "你应该跑测试" → AI 可以假装跑了 ❌
15
+ Stop Hook 检查 "未跑测试" → AI 物理无法跳过 ✅
16
+ ```
17
+
18
+ ## 六层架构
19
+
20
+ ```
21
+ L1 Context — Token 预算 + 上下文组装
22
+ L2 Guardrails — 8 检测器 + Role 网关
23
+ L3 Observability — EventBus + BehaviorTracker
24
+ L4 Orchestration — TaskEngine + Effects + ModelRouter
25
+ L5 Memory — KnowledgeBase + 衰减算法
26
+ L6 Evolution — Defect→Lesson→Rule→Hook 自进化
27
+ ```
28
+
29
+ ## 快速开始
30
+
31
+ ```bash
32
+ npm install -g @hongmaple0820/scale-engine
33
+ cd your-project
34
+ scale init --agent claude-code
35
+ scale doctor
36
+ scale create Spec "用户导出 Excel 功能"
37
+ scale transition SPEC-xxx refine
38
+ scale transition SPEC-xxx approve # ambiguity > 0.2 物理拦截
39
+ ```
40
+
41
+ ## CLI 命令 (13 个)
42
+
43
+ | 命令 | 说明 |
44
+ |------|------|
45
+ | `scale init` | 初始化 (.scale/ + hooks + CLAUDE.md) |
46
+ | `scale doctor` | 环境诊断 + 健康检查 |
47
+ | `scale create` | 创建 Artifact |
48
+ | `scale list` | 列表查询 |
49
+ | `scale show` | 详情 |
50
+ | `scale transition` | 状态迁移 (含 guard) |
51
+ | `scale role` | 角色切换 |
52
+ | `scale context` | 组装上下文 |
53
+ | `scale evolve` | 进化周期 |
54
+ | `scale stats` | 统计 |
55
+ | `scale session` | 会话管理 |
56
+ | `scale gate` | 网关检查 |
57
+
58
+ ## 11 种 Artifact · 4 级自进化 · 8 个检测器
59
+
60
+ 详见 `docs/` 目录。
61
+
62
+ ## License
63
+
64
+ MIT
@@ -0,0 +1,48 @@
1
+ export interface AdapterConfig {
2
+ projectDir: string;
3
+ scaleDir?: string;
4
+ agentType?: 'claude-code' | 'codex' | 'opencode' | 'cursor' | 'gemini';
5
+ }
6
+ export interface HookEntry {
7
+ matcher: string;
8
+ command: string;
9
+ timeout?: number;
10
+ }
11
+ export interface SettingsJson {
12
+ hooks?: Record<string, HookEntry[]>;
13
+ permissions?: {
14
+ allow?: string[];
15
+ deny?: string[];
16
+ };
17
+ mcpServers?: Record<string, unknown>;
18
+ }
19
+ export interface IAgentAdapter {
20
+ readonly agentType: string;
21
+ init(config: AdapterConfig): Promise<InitResult>;
22
+ getSettingsPath(): string;
23
+ getKnowledgeDocPath(): string;
24
+ generateSettings(): SettingsJson;
25
+ generateKnowledgeDoc(projectName: string, techStack?: string[]): string;
26
+ mergeSettings(existing: SettingsJson): SettingsJson;
27
+ isInstalled(): boolean;
28
+ }
29
+ export interface InitResult {
30
+ settingsPath: string;
31
+ knowledgeDocPath: string;
32
+ scaleDir: string;
33
+ created: string[];
34
+ skipped: string[];
35
+ }
36
+ export declare class ClaudeCodeAdapter implements IAgentAdapter {
37
+ readonly agentType = "claude-code";
38
+ private projectDir;
39
+ private scaleDir;
40
+ getSettingsPath(): string;
41
+ getKnowledgeDocPath(): string;
42
+ isInstalled(): boolean;
43
+ generateSettings(): SettingsJson;
44
+ mergeSettings(existing: SettingsJson): SettingsJson;
45
+ generateKnowledgeDoc(projectName: string, techStack?: string[]): string;
46
+ init(config: AdapterConfig): Promise<InitResult>;
47
+ }
48
+ export declare function createAdapter(agentType: string): IAgentAdapter;
@@ -0,0 +1,188 @@
1
+ // SCALE Engine — Claude Code Adapter (W8)
2
+ // 生成/合并 .claude/settings.json + CLAUDE.md
3
+ // 设计参考:docs/01-ARCHITECTURE.md 原则4 Headless优先
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { logger } from '../core/logger.js';
7
+ // ============================================================================
8
+ // Claude Code Adapter
9
+ // ============================================================================
10
+ export class ClaudeCodeAdapter {
11
+ agentType = 'claude-code';
12
+ projectDir = '.';
13
+ scaleDir = '.scale';
14
+ getSettingsPath() {
15
+ return join(this.projectDir, '.claude', 'settings.json');
16
+ }
17
+ getKnowledgeDocPath() {
18
+ return join(this.projectDir, 'CLAUDE.md');
19
+ }
20
+ isInstalled() {
21
+ return existsSync(this.getSettingsPath());
22
+ }
23
+ generateSettings() {
24
+ return {
25
+ hooks: {
26
+ SessionStart: [
27
+ { matcher: '', command: 'scale session start --agent claude-code --session-id $CLAUDE_SESSION_ID' },
28
+ ],
29
+ PreToolUse: [
30
+ { matcher: 'Bash', command: 'scale gate pre-tool Bash --args-json $TOOL_INPUT_JSON --session-id $CLAUDE_SESSION_ID' },
31
+ { matcher: 'Edit|Write|MultiEdit', command: 'scale gate pre-tool Edit --args-json $TOOL_INPUT_JSON --session-id $CLAUDE_SESSION_ID' },
32
+ ],
33
+ PostToolUse: [
34
+ { matcher: 'Edit|Write|MultiEdit', command: 'scale gate post-tool Edit --args-json $TOOL_INPUT_JSON --output-json $TOOL_OUTPUT_JSON --session-id $CLAUDE_SESSION_ID' },
35
+ { matcher: 'Bash', command: 'scale gate post-tool Bash --args-json $TOOL_INPUT_JSON --exit-code $TOOL_EXIT_CODE --session-id $CLAUDE_SESSION_ID' },
36
+ ],
37
+ Stop: [
38
+ { matcher: '', command: 'scale gate before-stop --session-id $CLAUDE_SESSION_ID' },
39
+ ],
40
+ SessionEnd: [
41
+ { matcher: '', command: 'scale session end --session-id $CLAUDE_SESSION_ID' },
42
+ ],
43
+ },
44
+ permissions: {
45
+ allow: ['Bash(scale:*)'],
46
+ },
47
+ };
48
+ }
49
+ mergeSettings(existing) {
50
+ const generated = this.generateSettings();
51
+ const merged = { ...existing };
52
+ // Merge hooks — add SCALE hooks without overwriting existing
53
+ if (!merged.hooks)
54
+ merged.hooks = {};
55
+ for (const [hookType, entries] of Object.entries(generated.hooks)) {
56
+ if (!merged.hooks[hookType])
57
+ merged.hooks[hookType] = [];
58
+ for (const entry of entries) {
59
+ const alreadyExists = merged.hooks[hookType].some((e) => e.command.includes('scale '));
60
+ if (!alreadyExists) {
61
+ merged.hooks[hookType].push(entry);
62
+ }
63
+ }
64
+ }
65
+ // Merge permissions
66
+ if (!merged.permissions)
67
+ merged.permissions = {};
68
+ if (!merged.permissions.allow)
69
+ merged.permissions.allow = [];
70
+ for (const perm of generated.permissions.allow) {
71
+ if (!merged.permissions.allow.includes(perm)) {
72
+ merged.permissions.allow.push(perm);
73
+ }
74
+ }
75
+ return merged;
76
+ }
77
+ generateKnowledgeDoc(projectName, techStack = []) {
78
+ const stackLine = techStack.length > 0
79
+ ? `\n## Tech Stack\n${techStack.map((t) => `- ${t}`).join('\n')}\n`
80
+ : '';
81
+ return `# ${projectName}
82
+ ${stackLine}
83
+ ## SCALE Engine Integration
84
+
85
+ This project uses SCALE Engine for AI engineering governance.
86
+
87
+ ### Commands
88
+ - \`scale create <type> <title>\` — Create artifact (Spec/Plan/Task/...)
89
+ - \`scale transition <id> <action>\` — Transition artifact state
90
+ - \`scale list --type Spec\` — List artifacts
91
+ - \`scale role activate <role>\` — Switch role (explorer/planner/implementer/reviewer)
92
+ - \`scale stats\` — Show engine stats
93
+
94
+ ### Workflow
95
+ 1. **Explore** → Role: explorer (Read/Grep only)
96
+ 2. **Plan** → Create Spec → refine → approve (guard: ambiguity ≤ 0.2)
97
+ 3. **Implement** → Role: implementer (Edit/Write/Bash unlocked)
98
+ 4. **Verify** → Must run tests before claiming done (Stop gate enforced)
99
+ 5. **Learn** → Defects auto-extract to lessons → rules → hooks
100
+
101
+ ### Rules
102
+ - 🔴 Dangerous commands (rm -rf, DROP TABLE) are physically blocked
103
+ - 🔴 Hardcoded secrets are blocked on Edit/Write
104
+ - 🟡 3 identical retries triggers brute-retry detection
105
+ - 🟡 Claiming done without running tests is blocked
106
+ - 🟢 All tool calls are tracked in .scale/events/
107
+ `;
108
+ }
109
+ async init(config) {
110
+ this.projectDir = config.projectDir;
111
+ this.scaleDir = config.scaleDir ?? join(config.projectDir, '.scale');
112
+ const created = [];
113
+ const skipped = [];
114
+ // 1. Create .scale/ directory structure
115
+ for (const dir of ['events', 'artifacts', 'rules', 'hooks', 'checkpoints']) {
116
+ const fullDir = join(this.scaleDir, dir);
117
+ if (!existsSync(fullDir)) {
118
+ mkdirSync(fullDir, { recursive: true });
119
+ created.push(fullDir);
120
+ }
121
+ else {
122
+ skipped.push(fullDir);
123
+ }
124
+ }
125
+ // 2. Create/merge .claude/settings.json
126
+ const settingsPath = this.getSettingsPath();
127
+ const claudeDir = join(this.projectDir, '.claude');
128
+ mkdirSync(claudeDir, { recursive: true });
129
+ if (existsSync(settingsPath)) {
130
+ const existing = JSON.parse(readFileSync(settingsPath, 'utf-8'));
131
+ const merged = this.mergeSettings(existing);
132
+ writeFileSync(settingsPath, JSON.stringify(merged, null, 2), 'utf-8');
133
+ skipped.push(settingsPath + ' (merged)');
134
+ }
135
+ else {
136
+ const settings = this.generateSettings();
137
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
138
+ created.push(settingsPath);
139
+ }
140
+ // 3. Create CLAUDE.md if not exists
141
+ const knowledgeDocPath = this.getKnowledgeDocPath();
142
+ if (!existsSync(knowledgeDocPath)) {
143
+ const projectName = config.projectDir.split(/[/\\]/).pop() ?? 'Project';
144
+ const content = this.generateKnowledgeDoc(projectName);
145
+ writeFileSync(knowledgeDocPath, content, 'utf-8');
146
+ created.push(knowledgeDocPath);
147
+ }
148
+ else {
149
+ skipped.push(knowledgeDocPath);
150
+ }
151
+ // 4. Create .gitignore for .scale/
152
+ const gitignorePath = join(this.scaleDir, '.gitignore');
153
+ if (!existsSync(gitignorePath)) {
154
+ writeFileSync(gitignorePath, `# SCALE Engine runtime data
155
+ *.db
156
+ *.db-journal
157
+ events/
158
+ checkpoints/
159
+ hooks/*.sh
160
+ `, 'utf-8');
161
+ created.push(gitignorePath);
162
+ }
163
+ logger.info({ created: created.length, skipped: skipped.length }, 'SCALE init completed');
164
+ return {
165
+ settingsPath,
166
+ knowledgeDocPath,
167
+ scaleDir: this.scaleDir,
168
+ created,
169
+ skipped,
170
+ };
171
+ }
172
+ }
173
+ // ============================================================================
174
+ // Adapter Factory
175
+ // ============================================================================
176
+ import { CodexAdapter } from './CodexAdapter.js';
177
+ // ...existing code...
178
+ export function createAdapter(agentType) {
179
+ switch (agentType) {
180
+ case 'claude-code':
181
+ return new ClaudeCodeAdapter();
182
+ case 'codex':
183
+ return new CodexAdapter();
184
+ default:
185
+ throw new Error(`Unsupported agent type: ${agentType}. Supported: claude-code, codex`);
186
+ }
187
+ }
188
+ //# sourceMappingURL=ClaudeCodeAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeCodeAdapter.js","sourceRoot":"","sources":["../../src/adapters/ClaudeCodeAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { IAgentAdapter, AdapterConfig, InitResult, SettingsJson } from './ClaudeCodeAdapter.js';
2
+ export declare class CodexAdapter implements IAgentAdapter {
3
+ readonly agentType = "codex";
4
+ private projectDir;
5
+ private scaleDir;
6
+ getSettingsPath(): string;
7
+ getKnowledgeDocPath(): string;
8
+ isInstalled(): boolean;
9
+ generateSettings(): SettingsJson;
10
+ generateCodexConfig(): string;
11
+ mergeSettings(existing: SettingsJson): SettingsJson;
12
+ generateKnowledgeDoc(projectName: string, techStack?: string[]): string;
13
+ init(config: AdapterConfig): Promise<InitResult>;
14
+ }
@@ -0,0 +1,153 @@
1
+ // SCALE Engine — Codex CLI Adapter (W11)
2
+ // 生成 .codex/config.toml + .codex/hooks.json + AGENTS.md
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ // ============================================================================
6
+ // Codex CLI Adapter
7
+ // ============================================================================
8
+ export class CodexAdapter {
9
+ agentType = 'codex';
10
+ projectDir = '.';
11
+ scaleDir = '.scale';
12
+ getSettingsPath() {
13
+ return join(this.projectDir, '.codex', 'hooks.json');
14
+ }
15
+ getKnowledgeDocPath() {
16
+ return join(this.projectDir, 'AGENTS.md');
17
+ }
18
+ isInstalled() {
19
+ return existsSync(this.getSettingsPath());
20
+ }
21
+ generateSettings() {
22
+ // Codex hooks.json format
23
+ return {
24
+ hooks: {
25
+ 'pre-exec': [
26
+ { matcher: '', command: 'scale gate pre-tool Bash --args-json "$ARGS" --session-id "$SESSION_ID"' },
27
+ ],
28
+ 'post-exec': [
29
+ { matcher: '', command: 'scale gate post-tool Bash --exit-code "$EXIT_CODE" --session-id "$SESSION_ID"' },
30
+ ],
31
+ },
32
+ };
33
+ }
34
+ generateCodexConfig() {
35
+ return `# SCALE Engine — Codex CLI config
36
+ # See: https://github.com/openai/codex
37
+
38
+ [model]
39
+ default = "o4-mini"
40
+
41
+ [approval]
42
+ # SCALE hooks handle safety gates
43
+ auto_approve = ["scale *"]
44
+
45
+ [environment]
46
+ SCALE_AGENT = "codex"
47
+ `;
48
+ }
49
+ mergeSettings(existing) {
50
+ const generated = this.generateSettings();
51
+ const merged = { ...existing };
52
+ if (!merged.hooks)
53
+ merged.hooks = {};
54
+ for (const [hookType, entries] of Object.entries(generated.hooks)) {
55
+ if (!merged.hooks[hookType])
56
+ merged.hooks[hookType] = [];
57
+ for (const entry of entries) {
58
+ const alreadyExists = merged.hooks[hookType].some((e) => e.command.includes('scale '));
59
+ if (!alreadyExists) {
60
+ merged.hooks[hookType].push(entry);
61
+ }
62
+ }
63
+ }
64
+ return merged;
65
+ }
66
+ generateKnowledgeDoc(projectName, techStack = []) {
67
+ const stackLine = techStack.length > 0
68
+ ? `\n## Tech Stack\n${techStack.map((t) => `- ${t}`).join('\n')}\n`
69
+ : '';
70
+ return `# ${projectName}
71
+ ${stackLine}
72
+ ## SCALE Engine Integration
73
+
74
+ This project uses SCALE Engine for AI engineering governance.
75
+
76
+ ### Workflow
77
+ 1. Explore → Plan → Implement → Verify → Learn
78
+ 2. All tool calls pass through SCALE gates
79
+ 3. Dangerous commands are physically blocked
80
+ 4. Tests must pass before completion
81
+
82
+ ### Commands
83
+ - \`scale create <type> <title>\` — Create artifact
84
+ - \`scale transition <id> <action>\` — State transition
85
+ - \`scale doctor\` — Health check
86
+ `;
87
+ }
88
+ async init(config) {
89
+ this.projectDir = config.projectDir;
90
+ this.scaleDir = config.scaleDir ?? join(config.projectDir, '.scale');
91
+ const created = [];
92
+ const skipped = [];
93
+ // 1. Create .scale/ structure
94
+ for (const dir of ['events', 'artifacts', 'rules', 'hooks', 'checkpoints']) {
95
+ const fullDir = join(this.scaleDir, dir);
96
+ if (!existsSync(fullDir)) {
97
+ mkdirSync(fullDir, { recursive: true });
98
+ created.push(fullDir);
99
+ }
100
+ else {
101
+ skipped.push(fullDir);
102
+ }
103
+ }
104
+ // 2. Create .codex/ directory
105
+ const codexDir = join(this.projectDir, '.codex');
106
+ mkdirSync(codexDir, { recursive: true });
107
+ // 3. Create/merge hooks.json
108
+ const hooksPath = this.getSettingsPath();
109
+ if (existsSync(hooksPath)) {
110
+ const existing = JSON.parse(readFileSync(hooksPath, 'utf-8'));
111
+ const merged = this.mergeSettings(existing);
112
+ writeFileSync(hooksPath, JSON.stringify(merged, null, 2), 'utf-8');
113
+ skipped.push(hooksPath + ' (merged)');
114
+ }
115
+ else {
116
+ writeFileSync(hooksPath, JSON.stringify(this.generateSettings(), null, 2), 'utf-8');
117
+ created.push(hooksPath);
118
+ }
119
+ // 4. Create config.toml
120
+ const configPath = join(codexDir, 'config.toml');
121
+ if (!existsSync(configPath)) {
122
+ writeFileSync(configPath, this.generateCodexConfig(), 'utf-8');
123
+ created.push(configPath);
124
+ }
125
+ else {
126
+ skipped.push(configPath);
127
+ }
128
+ // 5. Create AGENTS.md
129
+ const agentsPath = this.getKnowledgeDocPath();
130
+ if (!existsSync(agentsPath)) {
131
+ const projectName = config.projectDir.split(/[/\\]/).pop() ?? 'Project';
132
+ writeFileSync(agentsPath, this.generateKnowledgeDoc(projectName), 'utf-8');
133
+ created.push(agentsPath);
134
+ }
135
+ else {
136
+ skipped.push(agentsPath);
137
+ }
138
+ // 6. .gitignore
139
+ const gitignorePath = join(this.scaleDir, '.gitignore');
140
+ if (!existsSync(gitignorePath)) {
141
+ writeFileSync(gitignorePath, `*.db\n*.db-journal\nevents/\ncheckpoints/\nhooks/*.sh\n`, 'utf-8');
142
+ created.push(gitignorePath);
143
+ }
144
+ return {
145
+ settingsPath: hooksPath,
146
+ knowledgeDocPath: agentsPath,
147
+ scaleDir: this.scaleDir,
148
+ created,
149
+ skipped,
150
+ };
151
+ }
152
+ }
153
+ //# sourceMappingURL=CodexAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodexAdapter.js","sourceRoot":"","sources":["../../src/adapters/CodexAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};