@intutic/cli 0.1.0 → 0.2.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.
- package/dist/cli.js +309 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/benchmark.d.ts +31 -0
- package/dist/commands/benchmark.d.ts.map +1 -0
- package/dist/commands/benchmark.js +211 -0
- package/dist/commands/benchmark.js.map +1 -0
- package/dist/commands/connect.d.ts +8 -6
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +322 -82
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/enterprise-install.d.ts +36 -0
- package/dist/commands/enterprise-install.d.ts.map +1 -0
- package/dist/commands/enterprise-install.js +289 -0
- package/dist/commands/enterprise-install.js.map +1 -0
- package/dist/commands/eval.d.ts +13 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/eval.js +67 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/exec.d.ts +34 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +114 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/exec.test.d.ts +2 -0
- package/dist/commands/exec.test.d.ts.map +1 -0
- package/dist/commands/exec.test.js +29 -0
- package/dist/commands/exec.test.js.map +1 -0
- package/dist/commands/export.d.ts +21 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +116 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +28 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install-daemon.d.ts +61 -0
- package/dist/commands/install-daemon.d.ts.map +1 -0
- package/dist/commands/install-daemon.js +691 -0
- package/dist/commands/install-daemon.js.map +1 -0
- package/dist/commands/install-daemon.test.d.ts +2 -0
- package/dist/commands/install-daemon.test.d.ts.map +1 -0
- package/dist/commands/install-daemon.test.js +93 -0
- package/dist/commands/install-daemon.test.js.map +1 -0
- package/dist/commands/login.js +2 -2
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/mdm.d.ts +23 -0
- package/dist/commands/mdm.d.ts.map +1 -0
- package/dist/commands/mdm.js +134 -0
- package/dist/commands/mdm.js.map +1 -0
- package/dist/commands/sop-audit.d.ts +17 -0
- package/dist/commands/sop-audit.d.ts.map +1 -0
- package/dist/commands/sop-audit.js +136 -0
- package/dist/commands/sop-audit.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +53 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/syncContext.d.ts +18 -0
- package/dist/commands/syncContext.d.ts.map +1 -0
- package/dist/commands/syncContext.js +37 -0
- package/dist/commands/syncContext.js.map +1 -0
- package/dist/commands/traces.d.ts +13 -0
- package/dist/commands/traces.d.ts.map +1 -1
- package/dist/commands/traces.js +104 -10
- package/dist/commands/traces.js.map +1 -1
- package/dist/commands/whoami.js +1 -1
- package/dist/commands/whoami.js.map +1 -1
- package/dist/config/keychain.d.ts +28 -0
- package/dist/config/keychain.d.ts.map +1 -0
- package/dist/config/keychain.js +99 -0
- package/dist/config/keychain.js.map +1 -0
- package/dist/config/store.d.ts +3 -3
- package/dist/config/store.d.ts.map +1 -1
- package/dist/config/store.js +30 -6
- package/dist/config/store.js.map +1 -1
- package/dist/harness/aider.d.ts +4 -3
- package/dist/harness/aider.d.ts.map +1 -1
- package/dist/harness/aider.js +13 -27
- package/dist/harness/aider.js.map +1 -1
- package/dist/harness/claudeDesktop.d.ts +18 -0
- package/dist/harness/claudeDesktop.d.ts.map +1 -0
- package/dist/harness/claudeDesktop.js +69 -0
- package/dist/harness/claudeDesktop.js.map +1 -0
- package/dist/harness/cline.d.ts +13 -0
- package/dist/harness/cline.d.ts.map +1 -0
- package/dist/harness/cline.js +75 -0
- package/dist/harness/cline.js.map +1 -0
- package/dist/harness/codex.d.ts +4 -4
- package/dist/harness/codex.d.ts.map +1 -1
- package/dist/harness/codex.js +33 -21
- package/dist/harness/codex.js.map +1 -1
- package/dist/harness/continue.d.ts +14 -0
- package/dist/harness/continue.d.ts.map +1 -0
- package/dist/harness/continue.js +97 -0
- package/dist/harness/continue.js.map +1 -0
- package/dist/harness/cursor.d.ts +13 -1
- package/dist/harness/cursor.d.ts.map +1 -1
- package/dist/harness/cursor.js +59 -3
- package/dist/harness/cursor.js.map +1 -1
- package/dist/harness/detector.d.ts +1 -1
- package/dist/harness/detector.d.ts.map +1 -1
- package/dist/harness/detector.js +13 -1
- package/dist/harness/detector.js.map +1 -1
- package/dist/harness/goose.d.ts +13 -0
- package/dist/harness/goose.d.ts.map +1 -0
- package/dist/harness/goose.js +45 -0
- package/dist/harness/goose.js.map +1 -0
- package/dist/harness/n8n.d.ts +8 -4
- package/dist/harness/n8n.d.ts.map +1 -1
- package/dist/harness/n8n.js +108 -13
- package/dist/harness/n8n.js.map +1 -1
- package/dist/harness/openWebUI.d.ts +13 -0
- package/dist/harness/openWebUI.d.ts.map +1 -0
- package/dist/harness/openWebUI.js +25 -0
- package/dist/harness/openWebUI.js.map +1 -0
- package/dist/harness/openhands.d.ts +3 -3
- package/dist/harness/openhands.d.ts.map +1 -1
- package/dist/harness/openhands.js +13 -9
- package/dist/harness/openhands.js.map +1 -1
- package/dist/harness/rooCode.d.ts +14 -0
- package/dist/harness/rooCode.d.ts.map +1 -0
- package/dist/harness/rooCode.js +77 -0
- package/dist/harness/rooCode.js.map +1 -0
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +6 -0
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/vscodeSettingsWriter.d.ts +40 -0
- package/dist/harness/vscodeSettingsWriter.d.ts.map +1 -0
- package/dist/harness/vscodeSettingsWriter.js +116 -0
- package/dist/harness/vscodeSettingsWriter.js.map +1 -0
- package/dist/harness/windsurf.d.ts +13 -1
- package/dist/harness/windsurf.d.ts.map +1 -1
- package/dist/harness/windsurf.js +58 -3
- package/dist/harness/windsurf.js.map +1 -1
- package/dist/lib/api.d.ts +2 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +3 -0
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/envInjector.d.ts +24 -0
- package/dist/lib/envInjector.d.ts.map +1 -0
- package/dist/lib/envInjector.js +146 -0
- package/dist/lib/envInjector.js.map +1 -0
- package/dist/lib/envInjector.test.d.ts +2 -0
- package/dist/lib/envInjector.test.d.ts.map +1 -0
- package/dist/lib/envInjector.test.js +32 -0
- package/dist/lib/envInjector.test.js.map +1 -0
- package/dist/lib/gitHooks.d.ts +19 -0
- package/dist/lib/gitHooks.d.ts.map +1 -0
- package/dist/lib/gitHooks.js +58 -0
- package/dist/lib/gitHooks.js.map +1 -0
- package/dist/lib/onboarding.d.ts +17 -0
- package/dist/lib/onboarding.d.ts.map +1 -0
- package/dist/lib/onboarding.js +164 -0
- package/dist/lib/onboarding.js.map +1 -0
- package/dist/lib/process.d.ts +53 -0
- package/dist/lib/process.d.ts.map +1 -0
- package/dist/lib/process.js +181 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/lib/process.test.d.ts +2 -0
- package/dist/lib/process.test.d.ts.map +1 -0
- package/dist/lib/process.test.js +44 -0
- package/dist/lib/process.test.js.map +1 -0
- package/package.json +39 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aider.d.ts","sourceRoot":"","sources":["../../src/harness/aider.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"aider.d.ts","sourceRoot":"","sources":["../../src/harness/aider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAMjD,eAAO,MAAM,YAAY,EAAE,eAiC1B,CAAA"}
|
package/dist/harness/aider.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Aider adapter
|
|
2
|
+
* aider.ts — Aider adapter (full implementation with safe YAML merge).
|
|
3
3
|
*
|
|
4
|
-
* Writes SOP content into
|
|
5
|
-
*
|
|
4
|
+
* Writes SOP content into .aider.conf.yml using the aiderConfigMerger
|
|
5
|
+
* which safely merges proxy keys and strips dangerous auto-exec keys
|
|
6
|
+
* (test-cmd, lint-cmd) that Aider auto-executes on startup.
|
|
6
7
|
*
|
|
7
8
|
* HLD §3.14 — Harness Onboarding Matrix
|
|
8
9
|
* @module
|
|
9
10
|
*/
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
11
|
+
import { access } from 'node:fs/promises';
|
|
12
|
+
import { join } from 'node:path';
|
|
12
13
|
import { HarnessType } from '@intutic/shared-types';
|
|
13
14
|
import { hashFile } from '../lib/hash.js';
|
|
14
|
-
import {
|
|
15
|
+
import { mergeAiderConfig } from '@intutic/sync-daemon/harness/aiderConfigMerger';
|
|
15
16
|
const CONFIG_FILE = '.aider.conf.yml';
|
|
16
17
|
export const aiderAdapter = {
|
|
17
18
|
type: HarnessType.AIDER,
|
|
@@ -26,28 +27,13 @@ export const aiderAdapter = {
|
|
|
26
27
|
}
|
|
27
28
|
},
|
|
28
29
|
async writeConfig(workspaceRoot, sops, proxyUrl) {
|
|
29
|
-
if (sops.length === 0)
|
|
30
|
-
return null;
|
|
31
30
|
const filePath = join(workspaceRoot, CONFIG_FILE);
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
'# Intutic Governance Rules (auto-generated)',
|
|
39
|
-
'# DO NOT EDIT — managed by intutic sync daemon',
|
|
40
|
-
`# Last sync: ${newIso()}`,
|
|
41
|
-
'',
|
|
42
|
-
`# Proxy URL: ${proxyUrl}`,
|
|
43
|
-
'',
|
|
44
|
-
'extra-instructions: |',
|
|
45
|
-
...instructions.split('\n').map((line) => ` ${line}`),
|
|
46
|
-
'',
|
|
47
|
-
].join('\n');
|
|
48
|
-
await mkdir(dirname(filePath), { recursive: true });
|
|
49
|
-
await writeFile(tmpPath, yaml, 'utf-8');
|
|
50
|
-
await rename(tmpPath, filePath);
|
|
31
|
+
const sopsText = sops.length > 0
|
|
32
|
+
? sops.map((sop) => `## ${sop.title}\n\n${sop.content}`).join('\n\n---\n\n')
|
|
33
|
+
: undefined;
|
|
34
|
+
// Safe merge: strips test-cmd/lint-cmd, preserves all other user keys,
|
|
35
|
+
// injects proxy URL as openai-api-base and anthropic-api-base
|
|
36
|
+
await mergeAiderConfig(filePath, proxyUrl, sopsText);
|
|
51
37
|
return filePath;
|
|
52
38
|
},
|
|
53
39
|
async readCurrentHash(workspaceRoot) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aider.js","sourceRoot":"","sources":["../../src/harness/aider.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"aider.js","sourceRoot":"","sources":["../../src/harness/aider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AAEjF,MAAM,WAAW,GAAG,iBAAiB,CAAA;AAErC,MAAM,CAAC,MAAM,YAAY,GAAoB;IAC3C,IAAI,EAAE,WAAW,CAAC,KAAK;IACvB,cAAc,EAAE,WAAW;IAE3B,KAAK,CAAC,MAAM,CAAC,aAAqB;QAChC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAA;YAC9C,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,aAAqB,EAAE,IAAoB,EAAE,QAAgB;QAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;QAEjD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;YAC9B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;YAC5E,CAAC,CAAC,SAAS,CAAA;QAEb,uEAAuE;QACvE,8DAA8D;QAC9D,MAAM,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACpD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,aAAqB;QACzC,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAA;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* claudeDesktop.ts — Claude Desktop adapter (drift guard only).
|
|
3
|
+
*
|
|
4
|
+
* Claude Desktop has no hook system and no proxy override capability.
|
|
5
|
+
* Its config file (claude_desktop_config.json) is writable by any user
|
|
6
|
+
* process, so we register it with the drift watcher to detect tampering
|
|
7
|
+
* (e.g., a malicious MCP server added by another tool).
|
|
8
|
+
*
|
|
9
|
+
* writeConfig() returns null — no governance content can be injected.
|
|
10
|
+
* readCurrentHash() returns the hash of the config file so the drift
|
|
11
|
+
* watcher can detect changes and emit a governance_drift incident.
|
|
12
|
+
*
|
|
13
|
+
* HLD §3.14 — Harness Onboarding Matrix
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import type { IHarnessAdapter } from './types.js';
|
|
17
|
+
export declare const claudeDesktopAdapter: IHarnessAdapter;
|
|
18
|
+
//# sourceMappingURL=claudeDesktop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeDesktop.d.ts","sourceRoot":"","sources":["../../src/harness/claudeDesktop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAiBjD,eAAO,MAAM,oBAAoB,EAAE,eA2BlC,CAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* claudeDesktop.ts — Claude Desktop adapter (drift guard only).
|
|
3
|
+
*
|
|
4
|
+
* Claude Desktop has no hook system and no proxy override capability.
|
|
5
|
+
* Its config file (claude_desktop_config.json) is writable by any user
|
|
6
|
+
* process, so we register it with the drift watcher to detect tampering
|
|
7
|
+
* (e.g., a malicious MCP server added by another tool).
|
|
8
|
+
*
|
|
9
|
+
* writeConfig() returns null — no governance content can be injected.
|
|
10
|
+
* readCurrentHash() returns the hash of the config file so the drift
|
|
11
|
+
* watcher can detect changes and emit a governance_drift incident.
|
|
12
|
+
*
|
|
13
|
+
* HLD §3.14 — Harness Onboarding Matrix
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { access } from 'node:fs/promises';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { HarnessType } from '@intutic/shared-types';
|
|
20
|
+
import { hashFile } from '../lib/hash.js';
|
|
21
|
+
/** Platform-specific path to claude_desktop_config.json. */
|
|
22
|
+
function getClaudeDesktopConfigPath() {
|
|
23
|
+
switch (process.platform) {
|
|
24
|
+
case 'darwin':
|
|
25
|
+
return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
26
|
+
case 'win32':
|
|
27
|
+
return join(process.env.APPDATA ?? homedir(), 'Claude', 'claude_desktop_config.json');
|
|
28
|
+
default: // linux / WSL
|
|
29
|
+
return join(homedir(), '.config', 'Claude', 'claude_desktop_config.json');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const CONFIG_PATH = getClaudeDesktopConfigPath();
|
|
33
|
+
export const claudeDesktopAdapter = {
|
|
34
|
+
type: HarnessType.CLAUDE_DESKTOP,
|
|
35
|
+
configFileName: CONFIG_PATH,
|
|
36
|
+
async detect(_workspaceRoot) {
|
|
37
|
+
// Check for /Applications/Claude.app (macOS)
|
|
38
|
+
try {
|
|
39
|
+
await access('/Applications/Claude.app');
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch { /* fall through */ }
|
|
43
|
+
// Check for the config file directly
|
|
44
|
+
try {
|
|
45
|
+
await access(CONFIG_PATH);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
/** No governance content can be injected into Claude Desktop. */
|
|
53
|
+
async writeConfig() {
|
|
54
|
+
return null;
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Hash the config file so the drift watcher can detect if an
|
|
58
|
+
* unauthorized MCP server entry is added between sync cycles.
|
|
59
|
+
*/
|
|
60
|
+
async readCurrentHash(_workspaceRoot) {
|
|
61
|
+
try {
|
|
62
|
+
return await hashFile(CONFIG_PATH);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=claudeDesktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeDesktop.js","sourceRoot":"","sources":["../../src/harness/claudeDesktop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,4DAA4D;AAC5D,SAAS,0BAA0B;IACjC,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAA;QAClG,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,EAAE,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAA;QACvF,SAAS,cAAc;YACrB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAA;IAC7E,CAAC;AACH,CAAC;AAED,MAAM,WAAW,GAAG,0BAA0B,EAAE,CAAA;AAEhD,MAAM,CAAC,MAAM,oBAAoB,GAAoB;IACnD,IAAI,EAAE,WAAW,CAAC,cAAc;IAChC,cAAc,EAAE,WAAW;IAE3B,KAAK,CAAC,MAAM,CAAC,cAAsB;QACjC,6CAA6C;QAC7C,IAAI,CAAC;YAAC,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YAAC,OAAO,IAAI,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAC1F,qCAAqC;QACrC,IAAI,CAAC;YAAC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;YAAC,OAAO,IAAI,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,KAAK,CAAA;QAAC,CAAC;IACvE,CAAC;IAED,iEAAiE;IACjE,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,cAAsB;QAC1C,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAA;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cline.ts — Cline adapter (full implementation).
|
|
3
|
+
*
|
|
4
|
+
* Detects the Cline VS Code extension, writes Intutic governance rules
|
|
5
|
+
* as .clinerules, injects the PreToolUse blocking hook into .clinerules/hooks/,
|
|
6
|
+
* and configures the proxy base URL via VS Code settings + .env.intutic sidecar.
|
|
7
|
+
*
|
|
8
|
+
* HLD §3.14 — Harness Onboarding Matrix
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import type { IHarnessAdapter } from './types.js';
|
|
12
|
+
export declare const clineAdapter: IHarnessAdapter;
|
|
13
|
+
//# sourceMappingURL=cline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cline.d.ts","sourceRoot":"","sources":["../../src/harness/cline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAQjD,eAAO,MAAM,YAAY,EAAE,eA4D1B,CAAA"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cline.ts — Cline adapter (full implementation).
|
|
3
|
+
*
|
|
4
|
+
* Detects the Cline VS Code extension, writes Intutic governance rules
|
|
5
|
+
* as .clinerules, injects the PreToolUse blocking hook into .clinerules/hooks/,
|
|
6
|
+
* and configures the proxy base URL via VS Code settings + .env.intutic sidecar.
|
|
7
|
+
*
|
|
8
|
+
* HLD §3.14 — Harness Onboarding Matrix
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { access, readdir, writeFile, rename, mkdir } from 'node:fs/promises';
|
|
12
|
+
import { join, dirname } from 'node:path';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { HarnessType } from '@intutic/shared-types';
|
|
15
|
+
import { hashFile } from '../lib/hash.js';
|
|
16
|
+
import { newIso } from '@intutic/id';
|
|
17
|
+
import { writeClineHooks } from '@intutic/sync-daemon/harness/clineHooks';
|
|
18
|
+
import { injectClineProxySettings } from './vscodeSettingsWriter.js';
|
|
19
|
+
const CONFIG_FILE = '.clinerules';
|
|
20
|
+
export const clineAdapter = {
|
|
21
|
+
type: HarnessType.CLINE,
|
|
22
|
+
configFileName: CONFIG_FILE,
|
|
23
|
+
async detect(workspaceRoot) {
|
|
24
|
+
// Check for .clinerules in workspace
|
|
25
|
+
try {
|
|
26
|
+
await access(join(workspaceRoot, CONFIG_FILE));
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// fall through
|
|
31
|
+
}
|
|
32
|
+
// Check for VS Code extension directory
|
|
33
|
+
try {
|
|
34
|
+
const extensionsDir = join(homedir(), '.vscode', 'extensions');
|
|
35
|
+
const entries = await readdir(extensionsDir);
|
|
36
|
+
return entries.some((entry) => entry.startsWith('saoudrizwan.claude-dev-'));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
async writeConfig(workspaceRoot, sops, proxyUrl) {
|
|
43
|
+
// 1. Write .clinerules text rules
|
|
44
|
+
const filePath = join(workspaceRoot, CONFIG_FILE);
|
|
45
|
+
const instructions = sops.length > 0
|
|
46
|
+
? sops.map((sop) => `## ${sop.title}\n\n${sop.content}`).join('\n\n---\n\n')
|
|
47
|
+
: '# Intutic governance active — no SOP rules configured yet.';
|
|
48
|
+
const content = [
|
|
49
|
+
'# Intutic Governance Rules (auto-generated)',
|
|
50
|
+
'# DO NOT EDIT — managed by intutic sync daemon',
|
|
51
|
+
`# Last sync: ${newIso()}`,
|
|
52
|
+
'',
|
|
53
|
+
instructions,
|
|
54
|
+
'',
|
|
55
|
+
].join('\n');
|
|
56
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
57
|
+
const tmp = filePath + '.intutic-tmp';
|
|
58
|
+
await writeFile(tmp, content, 'utf-8');
|
|
59
|
+
await rename(tmp, filePath);
|
|
60
|
+
// 2. Write PreToolUse blocking hooks into .clinerules/hooks/
|
|
61
|
+
await writeClineHooks(workspaceRoot, proxyUrl);
|
|
62
|
+
// 3. Inject proxy URL into VS Code settings + .env.intutic sidecar
|
|
63
|
+
await injectClineProxySettings(workspaceRoot, proxyUrl);
|
|
64
|
+
return filePath;
|
|
65
|
+
},
|
|
66
|
+
async readCurrentHash(workspaceRoot) {
|
|
67
|
+
try {
|
|
68
|
+
return await hashFile(join(workspaceRoot, CONFIG_FILE));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=cline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cline.js","sourceRoot":"","sources":["../../src/harness/cline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAEpE,MAAM,WAAW,GAAG,aAAa,CAAA;AAEjC,MAAM,CAAC,MAAM,YAAY,GAAoB;IAC3C,IAAI,EAAE,WAAW,CAAC,KAAK;IACvB,cAAc,EAAE,WAAW;IAE3B,KAAK,CAAC,MAAM,CAAC,aAAqB;QAChC,qCAAqC;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAA;YAC9C,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,YAAY,CAAC,CAAA;YAC9D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;YAC5C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAA;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,aAAqB,EAAE,IAAoB,EAAE,QAAgB;QAC7E,kCAAkC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;QACjD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;YAClC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;YAC5E,CAAC,CAAC,4DAA4D,CAAA;QAEhE,MAAM,OAAO,GAAG;YACd,6CAA6C;YAC7C,gDAAgD;YAChD,gBAAgB,MAAM,EAAE,EAAE;YAC1B,EAAE;YACF,YAAY;YACZ,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEZ,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACnD,MAAM,GAAG,GAAG,QAAQ,GAAG,cAAc,CAAA;QACrC,MAAM,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACtC,MAAM,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAE3B,6DAA6D;QAC7D,MAAM,eAAe,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;QAE9C,mEAAmE;QACnE,MAAM,wBAAwB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;QAEvD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,aAAqB;QACzC,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAA;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF,CAAA"}
|
package/dist/harness/codex.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Codex adapter
|
|
2
|
+
* codex.ts — Codex adapter (updated: also writes ~/.codex/config.toml).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* In addition to the workspace .env.intutic file, writes
|
|
5
|
+
* ~/.codex/config.toml with model_providers.litellm.base_url so Codex
|
|
6
|
+
* routes LLM calls through the Intutic proxy even without env var sourcing.
|
|
7
7
|
*
|
|
8
8
|
* HLD §3.14 — Harness Onboarding Matrix
|
|
9
9
|
* @module
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAOjD,eAAO,MAAM,YAAY,EAAE,eAkE1B,CAAA"}
|
package/dist/harness/codex.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Codex adapter
|
|
2
|
+
* codex.ts — Codex adapter (updated: also writes ~/.codex/config.toml).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* In addition to the workspace .env.intutic file, writes
|
|
5
|
+
* ~/.codex/config.toml with model_providers.litellm.base_url so Codex
|
|
6
|
+
* routes LLM calls through the Intutic proxy even without env var sourcing.
|
|
7
7
|
*
|
|
8
8
|
* HLD §3.14 — Harness Onboarding Matrix
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
import { join, dirname } from 'node:path';
|
|
12
12
|
import { writeFile, rename, mkdir } from 'node:fs/promises';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
13
14
|
import { HarnessType } from '@intutic/shared-types';
|
|
14
15
|
import { hashFile } from '../lib/hash.js';
|
|
15
16
|
import { newIso } from '@intutic/id';
|
|
16
17
|
const CONFIG_FILE = '.env.intutic';
|
|
18
|
+
const CODEX_CONFIG = join(homedir(), '.codex', 'config.toml');
|
|
17
19
|
export const codexAdapter = {
|
|
18
20
|
type: HarnessType.CODEX,
|
|
19
21
|
configFileName: CONFIG_FILE,
|
|
20
22
|
async detect(_workspaceRoot) {
|
|
21
|
-
// Codex detection: check for CODEX_HOME env var or codex in PATH
|
|
22
23
|
if (process.env.CODEX_HOME)
|
|
23
24
|
return true;
|
|
24
|
-
// Basic PATH check
|
|
25
25
|
const pathDirs = (process.env.PATH ?? '').split(process.platform === 'win32' ? ';' : ':');
|
|
26
26
|
try {
|
|
27
27
|
const { accessSync } = await import('node:fs');
|
|
@@ -30,36 +30,48 @@ export const codexAdapter = {
|
|
|
30
30
|
accessSync(join(dir, 'codex'));
|
|
31
31
|
return true;
|
|
32
32
|
}
|
|
33
|
-
catch {
|
|
34
|
-
// Not in this dir
|
|
35
|
-
}
|
|
33
|
+
catch { /* not here */ }
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
|
-
catch {
|
|
39
|
-
// Fallback — not detected
|
|
40
|
-
}
|
|
36
|
+
catch { /* ignore */ }
|
|
41
37
|
return false;
|
|
42
38
|
},
|
|
43
39
|
async writeConfig(workspaceRoot, sops, proxyUrl) {
|
|
44
|
-
|
|
45
|
-
return null;
|
|
40
|
+
// 1. Workspace .env.intutic
|
|
46
41
|
const filePath = join(workspaceRoot, CONFIG_FILE);
|
|
47
|
-
const tmpPath = filePath + '.intutic-tmp';
|
|
48
42
|
const envContent = [
|
|
49
43
|
'# Intutic Governance Rules (auto-generated)',
|
|
50
44
|
'# DO NOT EDIT — managed by intutic sync daemon',
|
|
51
45
|
`# Last sync: ${newIso()}`,
|
|
52
46
|
'# Source this file: source .env.intutic',
|
|
53
47
|
'',
|
|
54
|
-
`ANTHROPIC_BASE_URL
|
|
55
|
-
`OPENAI_BASE_URL
|
|
56
|
-
`INTUTIC_PROXY_URL
|
|
57
|
-
`INTUTIC_SOP_COUNT=${sops.length}`,
|
|
48
|
+
`export ANTHROPIC_BASE_URL="${proxyUrl}"`,
|
|
49
|
+
`export OPENAI_BASE_URL="${proxyUrl}"`,
|
|
50
|
+
`export INTUTIC_PROXY_URL="${proxyUrl}"`,
|
|
51
|
+
`export INTUTIC_SOP_COUNT=${sops.length}`,
|
|
58
52
|
'',
|
|
59
53
|
].join('\n');
|
|
60
54
|
await mkdir(dirname(filePath), { recursive: true });
|
|
61
|
-
|
|
62
|
-
await
|
|
55
|
+
const tmpEnv = filePath + '.intutic-tmp';
|
|
56
|
+
await writeFile(tmpEnv, envContent, 'utf-8');
|
|
57
|
+
await rename(tmpEnv, filePath);
|
|
58
|
+
// 2. ~/.codex/config.toml — persists proxy across sessions without env sourcing
|
|
59
|
+
const codexToml = [
|
|
60
|
+
'# Intutic proxy config (auto-generated)',
|
|
61
|
+
'# DO NOT EDIT — managed by intutic sync daemon',
|
|
62
|
+
`# Last sync: ${newIso()}`,
|
|
63
|
+
'',
|
|
64
|
+
'[model_providers.litellm]',
|
|
65
|
+
`base_url = "${proxyUrl}"`,
|
|
66
|
+
'',
|
|
67
|
+
'[model_providers.openai]',
|
|
68
|
+
`base_url = "${proxyUrl}"`,
|
|
69
|
+
'',
|
|
70
|
+
].join('\n');
|
|
71
|
+
await mkdir(dirname(CODEX_CONFIG), { recursive: true });
|
|
72
|
+
const tmpToml = CODEX_CONFIG + '.intutic-tmp';
|
|
73
|
+
await writeFile(tmpToml, codexToml, 'utf-8');
|
|
74
|
+
await rename(tmpToml, CODEX_CONFIG);
|
|
63
75
|
return filePath;
|
|
64
76
|
},
|
|
65
77
|
async readCurrentHash(workspaceRoot) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,WAAW,GAAG,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* continue.ts — Continue adapter (proxy URL injection).
|
|
3
|
+
*
|
|
4
|
+
* Detects the Continue AI coding assistant and merges the Intutic
|
|
5
|
+
* proxy URL as apiBase into each model entry in ~/.continue/config.yaml.
|
|
6
|
+
* Continue has no hook system so proxy routing (Vector B) is the only
|
|
7
|
+
* available governance mechanism.
|
|
8
|
+
*
|
|
9
|
+
* HLD §3.14 — Harness Onboarding Matrix
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { IHarnessAdapter } from './types.js';
|
|
13
|
+
export declare const continueAdapter: IHarnessAdapter;
|
|
14
|
+
//# sourceMappingURL=continue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continue.d.ts","sourceRoot":"","sources":["../../src/harness/continue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AASjD,eAAO,MAAM,eAAe,EAAE,eAgE7B,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* continue.ts — Continue adapter (proxy URL injection).
|
|
3
|
+
*
|
|
4
|
+
* Detects the Continue AI coding assistant and merges the Intutic
|
|
5
|
+
* proxy URL as apiBase into each model entry in ~/.continue/config.yaml.
|
|
6
|
+
* Continue has no hook system so proxy routing (Vector B) is the only
|
|
7
|
+
* available governance mechanism.
|
|
8
|
+
*
|
|
9
|
+
* HLD §3.14 — Harness Onboarding Matrix
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { access, readdir, readFile, writeFile, rename, mkdir } from 'node:fs/promises';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { HarnessType } from '@intutic/shared-types';
|
|
16
|
+
import { hashFile } from '../lib/hash.js';
|
|
17
|
+
import { newIso } from '@intutic/id';
|
|
18
|
+
const home = homedir();
|
|
19
|
+
const CONTINUE_DIR = join(home, '.continue');
|
|
20
|
+
const CONFIG_YAML = join(CONTINUE_DIR, 'config.yaml');
|
|
21
|
+
const CONFIG_JSON = join(CONTINUE_DIR, 'config.json');
|
|
22
|
+
export const continueAdapter = {
|
|
23
|
+
type: HarnessType.CONTINUE,
|
|
24
|
+
configFileName: CONFIG_YAML,
|
|
25
|
+
async detect(_workspaceRoot) {
|
|
26
|
+
for (const p of [CONFIG_YAML, CONFIG_JSON]) {
|
|
27
|
+
try {
|
|
28
|
+
await access(p);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch { /* fall through */ }
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const entries = await readdir(join(home, '.vscode', 'extensions'));
|
|
35
|
+
return entries.some((e) => e.startsWith('continue.continue-'));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
async writeConfig(_workspaceRoot, _sops, proxyUrl) {
|
|
42
|
+
// Merge apiBase into each model entry in config.yaml
|
|
43
|
+
let raw = '';
|
|
44
|
+
try {
|
|
45
|
+
raw = await readFile(CONFIG_YAML, 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
raw = '';
|
|
49
|
+
}
|
|
50
|
+
// Inject apiBase under each `- name:` model entry.
|
|
51
|
+
// Simple line-based approach that handles the common config.yaml structure.
|
|
52
|
+
const lines = raw.split('\n');
|
|
53
|
+
const result = [];
|
|
54
|
+
let inModels = false;
|
|
55
|
+
for (let i = 0; i < lines.length; i++) {
|
|
56
|
+
const line = lines[i];
|
|
57
|
+
result.push(line);
|
|
58
|
+
if (line.trim() === 'models:') {
|
|
59
|
+
inModels = true;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (inModels && line.trim().startsWith('- name:')) {
|
|
63
|
+
// After each model entry start, inject apiBase if not already present
|
|
64
|
+
const next = lines[i + 1] ?? '';
|
|
65
|
+
if (!next.trim().startsWith('apiBase:')) {
|
|
66
|
+
result.push(` apiBase: "${proxyUrl}"`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (inModels && line.trim() && !line.startsWith(' ') && !line.trim().startsWith('-') && !line.trim().startsWith('models:')) {
|
|
70
|
+
inModels = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// If config.yaml is empty or has no models section yet, write a minimal config
|
|
74
|
+
if (!raw.includes('models:')) {
|
|
75
|
+
result.push('# Intutic proxy config (auto-generated)');
|
|
76
|
+
result.push(`# Last sync: ${newIso()}`);
|
|
77
|
+
result.push('models:');
|
|
78
|
+
result.push(' - name: "Intutic Governed Model"');
|
|
79
|
+
result.push(` apiBase: "${proxyUrl}"`);
|
|
80
|
+
}
|
|
81
|
+
const content = result.join('\n');
|
|
82
|
+
await mkdir(CONTINUE_DIR, { recursive: true });
|
|
83
|
+
const tmp = CONFIG_YAML + '.intutic-tmp';
|
|
84
|
+
await writeFile(tmp, content, 'utf-8');
|
|
85
|
+
await rename(tmp, CONFIG_YAML);
|
|
86
|
+
return CONFIG_YAML;
|
|
87
|
+
},
|
|
88
|
+
async readCurrentHash(_workspaceRoot) {
|
|
89
|
+
try {
|
|
90
|
+
return await hashFile(CONFIG_YAML);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=continue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continue.js","sourceRoot":"","sources":["../../src/harness/continue.ts"],"names":[],"mappings":"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"}
|
package/dist/harness/cursor.d.ts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* cursor.ts — Cursor adapter (full implementation with 3-level hooks).
|
|
3
|
+
*
|
|
4
|
+
* Replaces the minimal createMarkdownAdapter stub with a full adapter that:
|
|
5
|
+
* - Writes .cursorrules governance text (existing behaviour, kept)
|
|
6
|
+
* - Injects hooks.json at project-level AND user-level
|
|
7
|
+
* - Enterprise system-level (/etc/cursor) is handled by enterprise-install CLI
|
|
8
|
+
*
|
|
9
|
+
* HLD §3.14 — Harness Onboarding Matrix
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { IHarnessAdapter } from './types.js';
|
|
13
|
+
export declare const cursorAdapter: IHarnessAdapter;
|
|
2
14
|
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/harness/cursor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/harness/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AASjD,eAAO,MAAM,aAAa,EAAE,eAgC3B,CAAA"}
|
package/dist/harness/cursor.js
CHANGED
|
@@ -1,9 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cursor adapter
|
|
2
|
+
* cursor.ts — Cursor adapter (full implementation with 3-level hooks).
|
|
3
|
+
*
|
|
4
|
+
* Replaces the minimal createMarkdownAdapter stub with a full adapter that:
|
|
5
|
+
* - Writes .cursorrules governance text (existing behaviour, kept)
|
|
6
|
+
* - Injects hooks.json at project-level AND user-level
|
|
7
|
+
* - Enterprise system-level (/etc/cursor) is handled by enterprise-install CLI
|
|
8
|
+
*
|
|
3
9
|
* HLD §3.14 — Harness Onboarding Matrix
|
|
4
10
|
* @module
|
|
5
11
|
*/
|
|
12
|
+
import { access } from 'node:fs/promises';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
6
15
|
import { HarnessType } from '@intutic/shared-types';
|
|
7
|
-
import {
|
|
8
|
-
|
|
16
|
+
import { hashFile } from '../lib/hash.js';
|
|
17
|
+
import { buildMarkdownContent } from './base.js';
|
|
18
|
+
import { writeCursorHooks } from '@intutic/sync-daemon/harness/cursorHooks';
|
|
19
|
+
import { writeFile, rename, mkdir } from 'node:fs/promises';
|
|
20
|
+
import { dirname } from 'node:path';
|
|
21
|
+
const CONFIG_FILE = '.cursorrules';
|
|
22
|
+
export const cursorAdapter = {
|
|
23
|
+
type: HarnessType.CURSOR,
|
|
24
|
+
configFileName: CONFIG_FILE,
|
|
25
|
+
async detect(workspaceRoot) {
|
|
26
|
+
// .cursorrules or .cursor/ directory
|
|
27
|
+
for (const marker of [CONFIG_FILE, '.cursor']) {
|
|
28
|
+
try {
|
|
29
|
+
await access(join(workspaceRoot, marker));
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch { /* fall through */ }
|
|
33
|
+
}
|
|
34
|
+
// ~/.cursor directory (user has Cursor installed)
|
|
35
|
+
try {
|
|
36
|
+
await access(join(homedir(), '.cursor'));
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
async writeConfig(workspaceRoot, sops, proxyUrl) {
|
|
44
|
+
// 1. Write .cursorrules markdown governance text
|
|
45
|
+
const filePath = join(workspaceRoot, CONFIG_FILE);
|
|
46
|
+
const content = buildMarkdownContent(sops, proxyUrl);
|
|
47
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
48
|
+
const tmp = filePath + '.intutic-tmp';
|
|
49
|
+
await writeFile(tmp, content, 'utf-8');
|
|
50
|
+
await rename(tmp, filePath);
|
|
51
|
+
// 2. Inject hooks.json at project + user level (writeSystemLevel=false;
|
|
52
|
+
// system level requires enterprise-install with sudo)
|
|
53
|
+
await writeCursorHooks(workspaceRoot, proxyUrl, '', false);
|
|
54
|
+
return filePath;
|
|
55
|
+
},
|
|
56
|
+
async readCurrentHash(workspaceRoot) {
|
|
57
|
+
try {
|
|
58
|
+
return await hashFile(join(workspaceRoot, CONFIG_FILE));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
9
65
|
//# sourceMappingURL=cursor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/harness/cursor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/harness/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAA;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,MAAM,WAAW,GAAG,cAAc,CAAA;AAElC,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC5C,IAAI,EAAE,WAAW,CAAC,MAAM;IACxB,cAAc,EAAE,WAAW;IAE3B,KAAK,CAAC,MAAM,CAAC,aAAqB;QAChC,qCAAqC;QACrC,KAAK,MAAM,MAAM,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC;gBAAC,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;gBAAC,OAAO,IAAI,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAC7F,CAAC;QACD,kDAAkD;QAClD,IAAI,CAAC;YAAC,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;YAAC,OAAO,IAAI,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,KAAK,CAAA;QAAC,CAAC;IACtF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,aAAqB,EAAE,IAAoB,EAAE,QAAgB;QAC7E,iDAAiD;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;QACjD,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACpD,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACnD,MAAM,GAAG,GAAG,QAAQ,GAAG,cAAc,CAAA;QACrC,MAAM,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACtC,MAAM,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAE3B,wEAAwE;QACxE,yDAAyD;QACzD,MAAM,gBAAgB,CAAC,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;QAE1D,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,aAAqB;QACzC,IAAI,CAAC;YAAC,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAA;QAAC,CAAC;IACvF,CAAC;CACF,CAAA"}
|