@hongmaple0820/scale-engine 0.5.0 → 0.7.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 (128) hide show
  1. package/LICENSE +15 -15
  2. package/README.md +64 -13
  3. package/dist/adapters/ClaudeCodeAdapter.d.ts +1 -1
  4. package/dist/adapters/ClaudeCodeAdapter.js +5 -3
  5. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
  6. package/dist/adapters/CodexAdapter.js +33 -31
  7. package/dist/adapters/CodexAdapter.js.map +1 -1
  8. package/dist/adapters/CursorAdapter.js +5 -3
  9. package/dist/adapters/CursorAdapter.js.map +1 -1
  10. package/dist/adapters/GeminiAdapter.js +5 -3
  11. package/dist/adapters/GeminiAdapter.js.map +1 -1
  12. package/dist/adapters/HermesAdapter.js +5 -3
  13. package/dist/adapters/HermesAdapter.js.map +1 -1
  14. package/dist/adapters/OpenClawAdapter.js +5 -3
  15. package/dist/adapters/OpenClawAdapter.js.map +1 -1
  16. package/dist/adapters/OpenCodeAdapter.js +5 -3
  17. package/dist/adapters/OpenCodeAdapter.js.map +1 -1
  18. package/dist/adapters/QCoderAdapter.d.ts +13 -0
  19. package/dist/adapters/QCoderAdapter.js +155 -0
  20. package/dist/adapters/QCoderAdapter.js.map +1 -0
  21. package/dist/adapters/TraeAdapter.d.ts +13 -0
  22. package/dist/adapters/TraeAdapter.js +155 -0
  23. package/dist/adapters/TraeAdapter.js.map +1 -0
  24. package/dist/adapters/VSCAdapter.d.ts +13 -0
  25. package/dist/adapters/VSCAdapter.js +155 -0
  26. package/dist/adapters/VSCAdapter.js.map +1 -0
  27. package/dist/adapters/WorkBuddyAdapter.d.ts +13 -0
  28. package/dist/adapters/WorkBuddyAdapter.js +155 -0
  29. package/dist/adapters/WorkBuddyAdapter.js.map +1 -0
  30. package/dist/adapters/index.d.ts +4 -0
  31. package/dist/adapters/index.js +13 -1
  32. package/dist/adapters/index.js.map +1 -1
  33. package/dist/agents/AgentManager.d.ts +14 -0
  34. package/dist/agents/AgentManager.js +85 -0
  35. package/dist/agents/AgentManager.js.map +1 -0
  36. package/dist/agents/IAgent.d.ts +53 -0
  37. package/dist/agents/IAgent.js +4 -0
  38. package/dist/agents/IAgent.js.map +1 -0
  39. package/dist/agents/definitions/debugger.d.ts +2 -0
  40. package/dist/agents/definitions/debugger.js +6 -0
  41. package/dist/agents/definitions/debugger.js.map +1 -0
  42. package/dist/agents/definitions/doc-writer.d.ts +2 -0
  43. package/dist/agents/definitions/doc-writer.js +6 -0
  44. package/dist/agents/definitions/doc-writer.js.map +1 -0
  45. package/dist/agents/definitions/implementer.d.ts +2 -0
  46. package/dist/agents/definitions/implementer.js +6 -0
  47. package/dist/agents/definitions/implementer.js.map +1 -0
  48. package/dist/agents/definitions/planner.d.ts +2 -0
  49. package/dist/agents/definitions/planner.js +6 -0
  50. package/dist/agents/definitions/planner.js.map +1 -0
  51. package/dist/agents/definitions/researcher.d.ts +2 -0
  52. package/dist/agents/definitions/researcher.js +6 -0
  53. package/dist/agents/definitions/researcher.js.map +1 -0
  54. package/dist/agents/definitions/reviewer.d.ts +2 -0
  55. package/dist/agents/definitions/reviewer.js +6 -0
  56. package/dist/agents/definitions/reviewer.js.map +1 -0
  57. package/dist/agents/definitions/security.d.ts +2 -0
  58. package/dist/agents/definitions/security.js +6 -0
  59. package/dist/agents/definitions/security.js.map +1 -0
  60. package/dist/agents/definitions/tester.d.ts +2 -0
  61. package/dist/agents/definitions/tester.js +6 -0
  62. package/dist/agents/definitions/tester.js.map +1 -0
  63. package/dist/agents/definitions${file}.d.ts +1 -0
  64. package/dist/agents/definitions${file}.js +14 -0
  65. package/dist/agents/definitions${file}.js.map +1 -0
  66. package/dist/agents/index.d.ts +15 -0
  67. package/dist/agents/index.js +34 -0
  68. package/dist/agents/index.js.map +1 -0
  69. package/dist/api/cli.js +6 -5
  70. package/dist/api/cli.js.map +1 -1
  71. package/dist/api/doctor.js +29 -12
  72. package/dist/api/doctor.js.map +1 -1
  73. package/dist/api/mcp.js +0 -5
  74. package/dist/api/mcp.js.map +1 -1
  75. package/dist/artifact/fsm.d.ts +5 -0
  76. package/dist/artifact/fsm.js +25 -3
  77. package/dist/artifact/fsm.js.map +1 -1
  78. package/dist/artifact/sqliteStore.js +90 -103
  79. package/dist/artifact/sqliteStore.js.map +1 -1
  80. package/dist/artifact/store.js +2 -4
  81. package/dist/artifact/store.js.map +1 -1
  82. package/dist/artifact/types.d.ts +3 -3
  83. package/dist/artifact/types.js +0 -3
  84. package/dist/artifact/types.js.map +1 -1
  85. package/dist/context/ContextBuilder.js +1 -4
  86. package/dist/context/ContextBuilder.js.map +1 -1
  87. package/dist/core/container.js +4 -2
  88. package/dist/core/container.js.map +1 -1
  89. package/dist/core/eventBus.js +5 -6
  90. package/dist/core/eventBus.js.map +1 -1
  91. package/dist/dashboard/index.d.ts +2 -0
  92. package/dist/dashboard/index.js +2 -0
  93. package/dist/dashboard/index.js.map +1 -0
  94. package/dist/dashboard/server.d.ts +52 -0
  95. package/dist/dashboard/server.js +83 -0
  96. package/dist/dashboard/server.js.map +1 -0
  97. package/dist/evolution/BehaviorTracker.js +2 -3
  98. package/dist/evolution/BehaviorTracker.js.map +1 -1
  99. package/dist/evolution/EvolutionEngine.js +34 -45
  100. package/dist/evolution/EvolutionEngine.js.map +1 -1
  101. package/dist/evolution/PatternExtractor.d.ts +40 -0
  102. package/dist/evolution/PatternExtractor.js +83 -0
  103. package/dist/evolution/PatternExtractor.js.map +1 -0
  104. package/dist/evolution/SkillCreator.d.ts +40 -0
  105. package/dist/evolution/SkillCreator.js +118 -0
  106. package/dist/evolution/SkillCreator.js.map +1 -0
  107. package/dist/guardrails/Gateway.js +6 -7
  108. package/dist/guardrails/Gateway.js.map +1 -1
  109. package/dist/guardrails/advancedDetectors.d.ts +12 -0
  110. package/dist/guardrails/advancedDetectors.js +78 -28
  111. package/dist/guardrails/advancedDetectors.js.map +1 -1
  112. package/dist/guardrails/detectors.js +24 -14
  113. package/dist/guardrails/detectors.js.map +1 -1
  114. package/dist/index.d.ts +12 -1
  115. package/dist/index.js +11 -2
  116. package/dist/index.js.map +1 -1
  117. package/dist/knowledge/KnowledgeBase.js +2 -3
  118. package/dist/knowledge/KnowledgeBase.js.map +1 -1
  119. package/dist/knowledge/SQLiteKnowledgeBase.d.ts +28 -0
  120. package/dist/knowledge/SQLiteKnowledgeBase.js +175 -0
  121. package/dist/knowledge/SQLiteKnowledgeBase.js.map +1 -0
  122. package/dist/routing/ModelRouter.js +0 -2
  123. package/dist/routing/ModelRouter.js.map +1 -1
  124. package/dist/skills/SkillDiscovery.js +8 -1
  125. package/dist/skills/SkillDiscovery.js.map +1 -1
  126. package/dist/tasks/TaskEngine.js +25 -5
  127. package/dist/tasks/TaskEngine.js.map +1 -1
  128. package/package.json +8 -2
@@ -0,0 +1,155 @@
1
+ // SCALE Engine — QCoder (Qwen Code) Adapter
2
+ // 生成 .qwen/settings.json + QWEN.md
3
+ // Qwen Code: 阿里通义千问 CLI (https://github.com/QwenLM/qwen-code)
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { logger } from '../core/logger.js';
7
+ // ============================================================================
8
+ // QCoder Adapter
9
+ // ============================================================================
10
+ export class QCoderAdapter {
11
+ constructor() {
12
+ this.agentType = 'qcoder';
13
+ this.projectDir = '.';
14
+ this.scaleDir = '.scale';
15
+ }
16
+ getSettingsPath() {
17
+ return join(this.projectDir, '.qwen', 'settings.json');
18
+ }
19
+ getKnowledgeDocPath() {
20
+ return join(this.projectDir, 'QWEN.md');
21
+ }
22
+ isInstalled() {
23
+ return existsSync(join(this.projectDir, '.qwen'));
24
+ }
25
+ generateSettings() {
26
+ return {
27
+ hooks: {
28
+ 'pre-exec': [
29
+ { matcher: '', command: 'scale gate pre-tool Bash --args-json "$ARGS" --session-id "$SESSION_ID"' },
30
+ { matcher: 'edit|write', command: 'scale gate pre-tool Edit --args-json "$ARGS" --session-id "$SESSION_ID"' },
31
+ ],
32
+ 'post-exec': [
33
+ { matcher: 'edit|write', command: 'scale gate post-tool Edit --args-json "$ARGS" --exit-code "$EXIT_CODE" --session-id "$SESSION_ID"' },
34
+ { matcher: '', command: 'scale gate post-tool Bash --args-json "$ARGS" --exit-code "$EXIT_CODE" --session-id "$SESSION_ID"' },
35
+ ],
36
+ 'before-stop': [
37
+ { matcher: '', command: 'scale gate before-stop --session-id "$SESSION_ID"' },
38
+ ],
39
+ },
40
+ permissions: {
41
+ allow: ['scale:*'],
42
+ },
43
+ };
44
+ }
45
+ mergeSettings(existing) {
46
+ const generated = this.generateSettings();
47
+ const merged = { ...existing };
48
+ if (!merged.hooks)
49
+ merged.hooks = {};
50
+ for (const [hookType, entries] of Object.entries(generated.hooks)) {
51
+ if (!merged.hooks[hookType])
52
+ merged.hooks[hookType] = [];
53
+ for (const entry of entries) {
54
+ const alreadyExists = merged.hooks[hookType].some((e) => e.command.includes('scale '));
55
+ if (!alreadyExists) {
56
+ merged.hooks[hookType].push(entry);
57
+ }
58
+ }
59
+ }
60
+ if (!merged.permissions)
61
+ merged.permissions = {};
62
+ if (!merged.permissions.allow)
63
+ merged.permissions.allow = [];
64
+ for (const perm of generated.permissions.allow) {
65
+ if (!merged.permissions.allow.includes(perm)) {
66
+ merged.permissions.allow.push(perm);
67
+ }
68
+ }
69
+ return merged;
70
+ }
71
+ generateKnowledgeDoc(projectName, techStack = []) {
72
+ const stackLine = techStack.length > 0
73
+ ? `\n## Tech Stack\n${techStack.map((t) => `- ${t}`).join('\n')}\n`
74
+ : '';
75
+ return `# ${projectName}
76
+ ${stackLine}
77
+ ## SCALE Engine Integration (QCoder / Qwen Code)
78
+
79
+ This project uses SCALE Engine for AI engineering governance via Qwen Code CLI.
80
+
81
+ ### Commands
82
+ - \`scale create <type> <title>\` — Create artifact
83
+ - \`scale transition <id> <action>\` — Transition artifact state
84
+ - \`scale list --type Spec\` — List artifacts
85
+ - \`scale role activate <role>\` — Switch role
86
+ - \`scale doctor\` — Health check
87
+
88
+ ### Workflow
89
+ 1. **Explore** → Role: explorer (Read/Grep only)
90
+ 2. **Plan** → Create Spec → refine → approve (guard: ambiguity ≤ 0.2)
91
+ 3. **Implement** → Role: implementer (Edit/Write/Bash unlocked)
92
+ 4. **Verify** → Must run tests before claiming done
93
+ 5. **Learn** → Defects → Lessons → Rules → Hooks
94
+
95
+ ### Rules
96
+ - 🔴 Dangerous commands are physically blocked
97
+ - 🔴 Hardcoded secrets are blocked on Edit/Write
98
+ - 🟡 3 identical retries triggers brute-retry detection
99
+ - 🟡 Claiming done without running tests is blocked
100
+ - 🟢 All tool calls are tracked in .scale/events/
101
+ `;
102
+ }
103
+ async init(config) {
104
+ this.projectDir = config.projectDir;
105
+ this.scaleDir = config.scaleDir ?? join(config.projectDir, '.scale');
106
+ const created = [];
107
+ const skipped = [];
108
+ for (const dir of ['events', 'artifacts', 'rules', 'hooks', 'checkpoints']) {
109
+ const fullDir = join(this.scaleDir, dir);
110
+ if (!existsSync(fullDir)) {
111
+ mkdirSync(fullDir, { recursive: true });
112
+ created.push(fullDir);
113
+ }
114
+ else {
115
+ skipped.push(fullDir);
116
+ }
117
+ }
118
+ const qwenDir = join(this.projectDir, '.qwen');
119
+ mkdirSync(qwenDir, { recursive: true });
120
+ const settingsPath = this.getSettingsPath();
121
+ if (existsSync(settingsPath)) {
122
+ const existing = JSON.parse(readFileSync(settingsPath, 'utf-8'));
123
+ const merged = this.mergeSettings(existing);
124
+ writeFileSync(settingsPath, JSON.stringify(merged, null, 2), 'utf-8');
125
+ skipped.push(settingsPath + ' (merged)');
126
+ }
127
+ else {
128
+ writeFileSync(settingsPath, JSON.stringify(this.generateSettings(), null, 2), 'utf-8');
129
+ created.push(settingsPath);
130
+ }
131
+ const knowledgeDocPath = this.getKnowledgeDocPath();
132
+ if (!existsSync(knowledgeDocPath)) {
133
+ const projectName = config.projectDir.split(/[/\\]/).pop() ?? 'Project';
134
+ writeFileSync(knowledgeDocPath, this.generateKnowledgeDoc(projectName), 'utf-8');
135
+ created.push(knowledgeDocPath);
136
+ }
137
+ else {
138
+ skipped.push(knowledgeDocPath);
139
+ }
140
+ const gitignorePath = join(this.scaleDir, '.gitignore');
141
+ if (!existsSync(gitignorePath)) {
142
+ writeFileSync(gitignorePath, `*.db\n*.db-journal\nevents/\ncheckpoints/\nhooks/*.sh\n`, 'utf-8');
143
+ created.push(gitignorePath);
144
+ }
145
+ logger.info({ created: created.length, skipped: skipped.length }, 'SCALE init (qcoder) completed');
146
+ return {
147
+ settingsPath,
148
+ knowledgeDocPath,
149
+ scaleDir: this.scaleDir,
150
+ created,
151
+ skipped,
152
+ };
153
+ }
154
+ }
155
+ //# sourceMappingURL=QCoderAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QCoderAdapter.js","sourceRoot":"","sources":["../../src/adapters/QCoderAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { IAgentAdapter, AdapterConfig, InitResult, SettingsJson } from './ClaudeCodeAdapter.js';
2
+ export declare class TraeAdapter implements IAgentAdapter {
3
+ readonly agentType = "trae";
4
+ private projectDir;
5
+ private scaleDir;
6
+ getSettingsPath(): string;
7
+ getKnowledgeDocPath(): string;
8
+ isInstalled(): boolean;
9
+ generateSettings(): SettingsJson;
10
+ mergeSettings(existing: SettingsJson): SettingsJson;
11
+ generateKnowledgeDoc(projectName: string, techStack?: string[]): string;
12
+ init(config: AdapterConfig): Promise<InitResult>;
13
+ }
@@ -0,0 +1,155 @@
1
+ // SCALE Engine — Trae Adapter
2
+ // 生成 .trae/settings.json + TRAE.md
3
+ // Trae: ByteDance AI 编程助手 (https://www.trae.ai)
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { logger } from '../core/logger.js';
7
+ // ============================================================================
8
+ // Trae Adapter
9
+ // ============================================================================
10
+ export class TraeAdapter {
11
+ constructor() {
12
+ this.agentType = 'trae';
13
+ this.projectDir = '.';
14
+ this.scaleDir = '.scale';
15
+ }
16
+ getSettingsPath() {
17
+ return join(this.projectDir, '.trae', 'settings.json');
18
+ }
19
+ getKnowledgeDocPath() {
20
+ return join(this.projectDir, 'TRAE.md');
21
+ }
22
+ isInstalled() {
23
+ return existsSync(join(this.projectDir, '.trae'));
24
+ }
25
+ generateSettings() {
26
+ return {
27
+ hooks: {
28
+ 'pre-exec': [
29
+ { matcher: '', command: 'scale gate pre-tool Bash --args-json "$ARGS" --session-id "$SESSION_ID"' },
30
+ { matcher: 'edit|write', command: 'scale gate pre-tool Edit --args-json "$ARGS" --session-id "$SESSION_ID"' },
31
+ ],
32
+ 'post-exec': [
33
+ { matcher: 'edit|write', command: 'scale gate post-tool Edit --args-json "$ARGS" --exit-code "$EXIT_CODE" --session-id "$SESSION_ID"' },
34
+ { matcher: '', command: 'scale gate post-tool Bash --args-json "$ARGS" --exit-code "$EXIT_CODE" --session-id "$SESSION_ID"' },
35
+ ],
36
+ 'before-stop': [
37
+ { matcher: '', command: 'scale gate before-stop --session-id "$SESSION_ID"' },
38
+ ],
39
+ },
40
+ permissions: {
41
+ allow: ['scale:*'],
42
+ },
43
+ };
44
+ }
45
+ mergeSettings(existing) {
46
+ const generated = this.generateSettings();
47
+ const merged = { ...existing };
48
+ if (!merged.hooks)
49
+ merged.hooks = {};
50
+ for (const [hookType, entries] of Object.entries(generated.hooks)) {
51
+ if (!merged.hooks[hookType])
52
+ merged.hooks[hookType] = [];
53
+ for (const entry of entries) {
54
+ const alreadyExists = merged.hooks[hookType].some((e) => e.command.includes('scale '));
55
+ if (!alreadyExists) {
56
+ merged.hooks[hookType].push(entry);
57
+ }
58
+ }
59
+ }
60
+ if (!merged.permissions)
61
+ merged.permissions = {};
62
+ if (!merged.permissions.allow)
63
+ merged.permissions.allow = [];
64
+ for (const perm of generated.permissions.allow) {
65
+ if (!merged.permissions.allow.includes(perm)) {
66
+ merged.permissions.allow.push(perm);
67
+ }
68
+ }
69
+ return merged;
70
+ }
71
+ generateKnowledgeDoc(projectName, techStack = []) {
72
+ const stackLine = techStack.length > 0
73
+ ? `\n## Tech Stack\n${techStack.map((t) => `- ${t}`).join('\n')}\n`
74
+ : '';
75
+ return `# ${projectName}
76
+ ${stackLine}
77
+ ## SCALE Engine Integration (Trae)
78
+
79
+ This project uses SCALE Engine for AI engineering governance via Trae.
80
+
81
+ ### Commands
82
+ - \`scale create <type> <title>\` — Create artifact
83
+ - \`scale transition <id> <action>\` — Transition artifact state
84
+ - \`scale list --type Spec\` — List artifacts
85
+ - \`scale role activate <role>\` — Switch role
86
+ - \`scale doctor\` — Health check
87
+
88
+ ### Workflow
89
+ 1. **Explore** → Role: explorer (Read/Grep only)
90
+ 2. **Plan** → Create Spec → refine → approve (guard: ambiguity ≤ 0.2)
91
+ 3. **Implement** → Role: implementer (Edit/Write/Bash unlocked)
92
+ 4. **Verify** → Must run tests before claiming done
93
+ 5. **Learn** → Defects → Lessons → Rules → Hooks
94
+
95
+ ### Rules
96
+ - 🔴 Dangerous commands are physically blocked
97
+ - 🔴 Hardcoded secrets are blocked on Edit/Write
98
+ - 🟡 3 identical retries triggers brute-retry detection
99
+ - 🟡 Claiming done without running tests is blocked
100
+ - 🟢 All tool calls are tracked in .scale/events/
101
+ `;
102
+ }
103
+ async init(config) {
104
+ this.projectDir = config.projectDir;
105
+ this.scaleDir = config.scaleDir ?? join(config.projectDir, '.scale');
106
+ const created = [];
107
+ const skipped = [];
108
+ for (const dir of ['events', 'artifacts', 'rules', 'hooks', 'checkpoints']) {
109
+ const fullDir = join(this.scaleDir, dir);
110
+ if (!existsSync(fullDir)) {
111
+ mkdirSync(fullDir, { recursive: true });
112
+ created.push(fullDir);
113
+ }
114
+ else {
115
+ skipped.push(fullDir);
116
+ }
117
+ }
118
+ const traeDir = join(this.projectDir, '.trae');
119
+ mkdirSync(traeDir, { recursive: true });
120
+ const settingsPath = this.getSettingsPath();
121
+ if (existsSync(settingsPath)) {
122
+ const existing = JSON.parse(readFileSync(settingsPath, 'utf-8'));
123
+ const merged = this.mergeSettings(existing);
124
+ writeFileSync(settingsPath, JSON.stringify(merged, null, 2), 'utf-8');
125
+ skipped.push(settingsPath + ' (merged)');
126
+ }
127
+ else {
128
+ writeFileSync(settingsPath, JSON.stringify(this.generateSettings(), null, 2), 'utf-8');
129
+ created.push(settingsPath);
130
+ }
131
+ const knowledgeDocPath = this.getKnowledgeDocPath();
132
+ if (!existsSync(knowledgeDocPath)) {
133
+ const projectName = config.projectDir.split(/[/\\]/).pop() ?? 'Project';
134
+ writeFileSync(knowledgeDocPath, this.generateKnowledgeDoc(projectName), 'utf-8');
135
+ created.push(knowledgeDocPath);
136
+ }
137
+ else {
138
+ skipped.push(knowledgeDocPath);
139
+ }
140
+ const gitignorePath = join(this.scaleDir, '.gitignore');
141
+ if (!existsSync(gitignorePath)) {
142
+ writeFileSync(gitignorePath, `*.db\n*.db-journal\nevents/\ncheckpoints/\nhooks/*.sh\n`, 'utf-8');
143
+ created.push(gitignorePath);
144
+ }
145
+ logger.info({ created: created.length, skipped: skipped.length }, 'SCALE init (trae) completed');
146
+ return {
147
+ settingsPath,
148
+ knowledgeDocPath,
149
+ scaleDir: this.scaleDir,
150
+ created,
151
+ skipped,
152
+ };
153
+ }
154
+ }
155
+ //# sourceMappingURL=TraeAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraeAdapter.js","sourceRoot":"","sources":["../../src/adapters/TraeAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { IAgentAdapter, AdapterConfig, InitResult, SettingsJson } from './ClaudeCodeAdapter.js';
2
+ export declare class VSCAdapter implements IAgentAdapter {
3
+ readonly agentType = "vsc";
4
+ private projectDir;
5
+ private scaleDir;
6
+ getSettingsPath(): string;
7
+ getKnowledgeDocPath(): string;
8
+ isInstalled(): boolean;
9
+ generateSettings(): SettingsJson;
10
+ mergeSettings(existing: SettingsJson): SettingsJson;
11
+ generateKnowledgeDoc(projectName: string, techStack?: string[]): string;
12
+ init(config: AdapterConfig): Promise<InitResult>;
13
+ }
@@ -0,0 +1,155 @@
1
+ // SCALE Engine — VSC Adapter
2
+ // 生成 .vscode/scale.json + VSC.md
3
+ // VSC: VS Code Copilot CLI / agent runtime
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { logger } from '../core/logger.js';
7
+ // ============================================================================
8
+ // VSC Adapter
9
+ // ============================================================================
10
+ export class VSCAdapter {
11
+ constructor() {
12
+ this.agentType = 'vsc';
13
+ this.projectDir = '.';
14
+ this.scaleDir = '.scale';
15
+ }
16
+ getSettingsPath() {
17
+ return join(this.projectDir, '.vscode', 'scale.json');
18
+ }
19
+ getKnowledgeDocPath() {
20
+ return join(this.projectDir, 'VSC.md');
21
+ }
22
+ isInstalled() {
23
+ return existsSync(this.getSettingsPath());
24
+ }
25
+ generateSettings() {
26
+ return {
27
+ hooks: {
28
+ 'pre-exec': [
29
+ { matcher: '', command: 'scale gate pre-tool Bash --args-json "$ARGS" --session-id "$SESSION_ID"' },
30
+ { matcher: 'edit|write', command: 'scale gate pre-tool Edit --args-json "$ARGS" --session-id "$SESSION_ID"' },
31
+ ],
32
+ 'post-exec': [
33
+ { matcher: 'edit|write', command: 'scale gate post-tool Edit --args-json "$ARGS" --exit-code "$EXIT_CODE" --session-id "$SESSION_ID"' },
34
+ { matcher: '', command: 'scale gate post-tool Bash --args-json "$ARGS" --exit-code "$EXIT_CODE" --session-id "$SESSION_ID"' },
35
+ ],
36
+ 'before-stop': [
37
+ { matcher: '', command: 'scale gate before-stop --session-id "$SESSION_ID"' },
38
+ ],
39
+ },
40
+ permissions: {
41
+ allow: ['scale:*'],
42
+ },
43
+ };
44
+ }
45
+ mergeSettings(existing) {
46
+ const generated = this.generateSettings();
47
+ const merged = { ...existing };
48
+ if (!merged.hooks)
49
+ merged.hooks = {};
50
+ for (const [hookType, entries] of Object.entries(generated.hooks)) {
51
+ if (!merged.hooks[hookType])
52
+ merged.hooks[hookType] = [];
53
+ for (const entry of entries) {
54
+ const alreadyExists = merged.hooks[hookType].some((e) => e.command.includes('scale '));
55
+ if (!alreadyExists) {
56
+ merged.hooks[hookType].push(entry);
57
+ }
58
+ }
59
+ }
60
+ if (!merged.permissions)
61
+ merged.permissions = {};
62
+ if (!merged.permissions.allow)
63
+ merged.permissions.allow = [];
64
+ for (const perm of generated.permissions.allow) {
65
+ if (!merged.permissions.allow.includes(perm)) {
66
+ merged.permissions.allow.push(perm);
67
+ }
68
+ }
69
+ return merged;
70
+ }
71
+ generateKnowledgeDoc(projectName, techStack = []) {
72
+ const stackLine = techStack.length > 0
73
+ ? `\n## Tech Stack\n${techStack.map((t) => `- ${t}`).join('\n')}\n`
74
+ : '';
75
+ return `# ${projectName}
76
+ ${stackLine}
77
+ ## SCALE Engine Integration (VSC)
78
+
79
+ This project uses SCALE Engine for AI engineering governance via VS Code Copilot CLI.
80
+
81
+ ### Commands
82
+ - \`scale create <type> <title>\` — Create artifact
83
+ - \`scale transition <id> <action>\` — Transition artifact state
84
+ - \`scale list --type Spec\` — List artifacts
85
+ - \`scale role activate <role>\` — Switch role
86
+ - \`scale doctor\` — Health check
87
+
88
+ ### Workflow
89
+ 1. **Explore** → Role: explorer (Read/Grep only)
90
+ 2. **Plan** → Create Spec → refine → approve (guard: ambiguity ≤ 0.2)
91
+ 3. **Implement** → Role: implementer (Edit/Write/Bash unlocked)
92
+ 4. **Verify** → Must run tests before claiming done
93
+ 5. **Learn** → Defects → Lessons → Rules → Hooks
94
+
95
+ ### Rules
96
+ - 🔴 Dangerous commands are physically blocked
97
+ - 🔴 Hardcoded secrets are blocked on Edit/Write
98
+ - 🟡 3 identical retries triggers brute-retry detection
99
+ - 🟡 Claiming done without running tests is blocked
100
+ - 🟢 All tool calls are tracked in .scale/events/
101
+ `;
102
+ }
103
+ async init(config) {
104
+ this.projectDir = config.projectDir;
105
+ this.scaleDir = config.scaleDir ?? join(config.projectDir, '.scale');
106
+ const created = [];
107
+ const skipped = [];
108
+ for (const dir of ['events', 'artifacts', 'rules', 'hooks', 'checkpoints']) {
109
+ const fullDir = join(this.scaleDir, dir);
110
+ if (!existsSync(fullDir)) {
111
+ mkdirSync(fullDir, { recursive: true });
112
+ created.push(fullDir);
113
+ }
114
+ else {
115
+ skipped.push(fullDir);
116
+ }
117
+ }
118
+ const vscDir = join(this.projectDir, '.vscode');
119
+ mkdirSync(vscDir, { recursive: true });
120
+ const settingsPath = this.getSettingsPath();
121
+ if (existsSync(settingsPath)) {
122
+ const existing = JSON.parse(readFileSync(settingsPath, 'utf-8'));
123
+ const merged = this.mergeSettings(existing);
124
+ writeFileSync(settingsPath, JSON.stringify(merged, null, 2), 'utf-8');
125
+ skipped.push(settingsPath + ' (merged)');
126
+ }
127
+ else {
128
+ writeFileSync(settingsPath, JSON.stringify(this.generateSettings(), null, 2), 'utf-8');
129
+ created.push(settingsPath);
130
+ }
131
+ const knowledgeDocPath = this.getKnowledgeDocPath();
132
+ if (!existsSync(knowledgeDocPath)) {
133
+ const projectName = config.projectDir.split(/[/\\]/).pop() ?? 'Project';
134
+ writeFileSync(knowledgeDocPath, this.generateKnowledgeDoc(projectName), 'utf-8');
135
+ created.push(knowledgeDocPath);
136
+ }
137
+ else {
138
+ skipped.push(knowledgeDocPath);
139
+ }
140
+ const gitignorePath = join(this.scaleDir, '.gitignore');
141
+ if (!existsSync(gitignorePath)) {
142
+ writeFileSync(gitignorePath, `*.db\n*.db-journal\nevents/\ncheckpoints/\nhooks/*.sh\n`, 'utf-8');
143
+ created.push(gitignorePath);
144
+ }
145
+ logger.info({ created: created.length, skipped: skipped.length }, 'SCALE init (vsc) completed');
146
+ return {
147
+ settingsPath,
148
+ knowledgeDocPath,
149
+ scaleDir: this.scaleDir,
150
+ created,
151
+ skipped,
152
+ };
153
+ }
154
+ }
155
+ //# sourceMappingURL=VSCAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VSCAdapter.js","sourceRoot":"","sources":["../../src/adapters/VSCAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { IAgentAdapter, AdapterConfig, InitResult, SettingsJson } from './ClaudeCodeAdapter.js';
2
+ export declare class WorkBuddyAdapter implements IAgentAdapter {
3
+ readonly agentType = "workbuddy";
4
+ private projectDir;
5
+ private scaleDir;
6
+ getSettingsPath(): string;
7
+ getKnowledgeDocPath(): string;
8
+ isInstalled(): boolean;
9
+ generateSettings(): SettingsJson;
10
+ mergeSettings(existing: SettingsJson): SettingsJson;
11
+ generateKnowledgeDoc(projectName: string, techStack?: string[]): string;
12
+ init(config: AdapterConfig): Promise<InitResult>;
13
+ }