@nram-ai/setup-agents 0.0.1-pre.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/LICENSE +19 -0
- package/README.md +109 -0
- package/dist/helpers/configure/amp.d.ts +9 -0
- package/dist/helpers/configure/amp.js +49 -0
- package/dist/helpers/configure/amp.js.map +1 -0
- package/dist/helpers/configure/antigravity.d.ts +12 -0
- package/dist/helpers/configure/antigravity.js +74 -0
- package/dist/helpers/configure/antigravity.js.map +1 -0
- package/dist/helpers/configure/claude_code.d.ts +9 -0
- package/dist/helpers/configure/claude_code.js +119 -0
- package/dist/helpers/configure/claude_code.js.map +1 -0
- package/dist/helpers/configure/codex.d.ts +19 -0
- package/dist/helpers/configure/codex.js +76 -0
- package/dist/helpers/configure/codex.js.map +1 -0
- package/dist/helpers/configure/copilot.d.ts +11 -0
- package/dist/helpers/configure/copilot.js +64 -0
- package/dist/helpers/configure/copilot.js.map +1 -0
- package/dist/helpers/configure/cursor.d.ts +26 -0
- package/dist/helpers/configure/cursor.js +90 -0
- package/dist/helpers/configure/cursor.js.map +1 -0
- package/dist/helpers/configure/droid.d.ts +18 -0
- package/dist/helpers/configure/droid.js +70 -0
- package/dist/helpers/configure/droid.js.map +1 -0
- package/dist/helpers/configure/grok.d.ts +25 -0
- package/dist/helpers/configure/grok.js +93 -0
- package/dist/helpers/configure/grok.js.map +1 -0
- package/dist/helpers/configure/hermes.d.ts +22 -0
- package/dist/helpers/configure/hermes.js +107 -0
- package/dist/helpers/configure/hermes.js.map +1 -0
- package/dist/helpers/configure/junie.d.ts +10 -0
- package/dist/helpers/configure/junie.js +52 -0
- package/dist/helpers/configure/junie.js.map +1 -0
- package/dist/helpers/configure/kilo.d.ts +19 -0
- package/dist/helpers/configure/kilo.js +110 -0
- package/dist/helpers/configure/kilo.js.map +1 -0
- package/dist/helpers/configure/kimi.d.ts +10 -0
- package/dist/helpers/configure/kimi.js +75 -0
- package/dist/helpers/configure/kimi.js.map +1 -0
- package/dist/helpers/configure/kiro.d.ts +25 -0
- package/dist/helpers/configure/kiro.js +77 -0
- package/dist/helpers/configure/kiro.js.map +1 -0
- package/dist/helpers/configure/openclaw.d.ts +10 -0
- package/dist/helpers/configure/openclaw.js +72 -0
- package/dist/helpers/configure/openclaw.js.map +1 -0
- package/dist/helpers/configure/opencode.d.ts +18 -0
- package/dist/helpers/configure/opencode.js +72 -0
- package/dist/helpers/configure/opencode.js.map +1 -0
- package/dist/helpers/configure/pi.d.ts +10 -0
- package/dist/helpers/configure/pi.js +60 -0
- package/dist/helpers/configure/pi.js.map +1 -0
- package/dist/helpers/configure/trae.d.ts +11 -0
- package/dist/helpers/configure/trae.js +63 -0
- package/dist/helpers/configure/trae.js.map +1 -0
- package/dist/helpers/configure/vibe.d.ts +24 -0
- package/dist/helpers/configure/vibe.js +106 -0
- package/dist/helpers/configure/vibe.js.map +1 -0
- package/dist/helpers/configure/vscode.d.ts +18 -0
- package/dist/helpers/configure/vscode.js +81 -0
- package/dist/helpers/configure/vscode.js.map +1 -0
- package/dist/helpers/harnesses.d.ts +8 -0
- package/dist/helpers/harnesses.js +161 -0
- package/dist/helpers/harnesses.js.map +1 -0
- package/dist/helpers/instructions.d.ts +63 -0
- package/dist/helpers/instructions.js +175 -0
- package/dist/helpers/instructions.js.map +1 -0
- package/dist/helpers/paths.d.ts +130 -0
- package/dist/helpers/paths.js +211 -0
- package/dist/helpers/paths.js.map +1 -0
- package/dist/helpers/upsert.d.ts +197 -0
- package/dist/helpers/upsert.js +428 -0
- package/dist/helpers/upsert.js.map +1 -0
- package/dist/helpers/url.d.ts +15 -0
- package/dist/helpers/url.js +51 -0
- package/dist/helpers/url.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -0
- package/dist/setup.d.ts +17 -0
- package/dist/setup.js +296 -0
- package/dist/setup.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.js +50 -0
- package/dist/types.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026, Brandon Lehmann <brandonlehmann@gmail.com>
|
|
3
|
+
//
|
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
// in the Software without restriction, including without limitation the rights
|
|
7
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
// furnished to do so, subject to the following conditions:
|
|
10
|
+
//
|
|
11
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
// copies or substantial portions of the Software.
|
|
13
|
+
//
|
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
// SOFTWARE.
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.mcp_url = exports.normalize_base_url = void 0;
|
|
23
|
+
/**
|
|
24
|
+
* Normalizes an nram base URL: trims whitespace, requires http/https,
|
|
25
|
+
* and strips any trailing slash so that paths can be appended safely
|
|
26
|
+
*
|
|
27
|
+
* @param input the user-supplied base URL
|
|
28
|
+
* @returns the normalized base URL
|
|
29
|
+
* @throws Error when the input is not a valid http(s) URL
|
|
30
|
+
*/
|
|
31
|
+
const normalize_base_url = (input) => {
|
|
32
|
+
const trimmed = input.trim();
|
|
33
|
+
const url = new URL(trimmed); // throws on invalid input
|
|
34
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
35
|
+
throw new Error('The nram base URL must use http or https');
|
|
36
|
+
}
|
|
37
|
+
if (url.search.length !== 0 || url.hash.length !== 0) {
|
|
38
|
+
throw new Error('The nram base URL must not contain a query string or fragment');
|
|
39
|
+
}
|
|
40
|
+
const pathname = url.pathname.replace(/\/+$/, '');
|
|
41
|
+
return `${url.origin}${pathname}`;
|
|
42
|
+
};
|
|
43
|
+
exports.normalize_base_url = normalize_base_url;
|
|
44
|
+
/**
|
|
45
|
+
* Derives the MCP endpoint URL from a normalized base URL
|
|
46
|
+
*
|
|
47
|
+
* @param base_url the normalized nram base URL
|
|
48
|
+
*/
|
|
49
|
+
const mcp_url = (base_url) => `${base_url}/mcp`;
|
|
50
|
+
exports.mcp_url = mcp_url;
|
|
51
|
+
//# sourceMappingURL=url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/helpers/url.ts"],"names":[],"mappings":";AAAA,iEAAiE;AACjE,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAEZ;;;;;;;GAOG;AACI,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAAU,EAAE;IACxD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B;IAExD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAElD,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;AACtC,CAAC,CAAC;AAhBW,QAAA,kBAAkB,sBAgB7B;AAEF;;;;GAIG;AACI,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAU,EAAE,CAAC,GAAG,QAAQ,MAAM,CAAC;AAA1D,QAAA,OAAO,WAAmD"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
// Copyright (c) 2026, Brandon Lehmann <brandonlehmann@gmail.com>
|
|
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, EXPRESS OR
|
|
16
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
// SOFTWARE.
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
+
}
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
39
|
+
var ownKeys = function(o) {
|
|
40
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
41
|
+
var ar = [];
|
|
42
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
43
|
+
return ar;
|
|
44
|
+
};
|
|
45
|
+
return ownKeys(o);
|
|
46
|
+
};
|
|
47
|
+
return function (mod) {
|
|
48
|
+
if (mod && mod.__esModule) return mod;
|
|
49
|
+
var result = {};
|
|
50
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
51
|
+
__setModuleDefault(result, mod);
|
|
52
|
+
return result;
|
|
53
|
+
};
|
|
54
|
+
})();
|
|
55
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
+
const commander_1 = require("commander");
|
|
57
|
+
const instructions_1 = require("./helpers/instructions");
|
|
58
|
+
const url_1 = require("./helpers/url");
|
|
59
|
+
commander_1.program.name('npx @nram-ai/setup-agents')
|
|
60
|
+
.description('Helps to configure local harnesses to utilize Neural Ram');
|
|
61
|
+
commander_1.program.option('-s, --session-start', 'print out the session start protocol');
|
|
62
|
+
commander_1.program.option('-u, --url <url>', 'the base URL of your nram server (skips the prompt)');
|
|
63
|
+
commander_1.program.option('--skip-mcp', 'do not register the nram MCP server');
|
|
64
|
+
commander_1.program.option('--skip-instructions', 'do not inject the agent instructions (hook, AGENTS.md, or rules file)');
|
|
65
|
+
commander_1.program.parse();
|
|
66
|
+
const options = commander_1.program.opts();
|
|
67
|
+
if (options.sessionStart) {
|
|
68
|
+
// A SessionStart hook must never break an agent session: any failure
|
|
69
|
+
// falls down the chain (server, cache, GitHub, built-in notice) and the
|
|
70
|
+
// process always exits 0
|
|
71
|
+
(async () => {
|
|
72
|
+
let base_url;
|
|
73
|
+
try {
|
|
74
|
+
base_url = options.url !== undefined ? (0, url_1.normalize_base_url)(options.url) : undefined;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// an unparseable --url degrades to the cache/GitHub chain
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const { text } = await (0, instructions_1.resolve_instructions)(base_url, 'full', 3_000);
|
|
81
|
+
console.log(text);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
console.log((0, instructions_1.builtin_notice)('full'));
|
|
85
|
+
}
|
|
86
|
+
process.exit(0);
|
|
87
|
+
})();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// The interactive flow (and its dependencies: @clack/prompts, chalk, and
|
|
91
|
+
// smol-toml via the configurators) loads lazily so the --session-start
|
|
92
|
+
// fast path above, which runs at every agent session start, stays cheap
|
|
93
|
+
(async () => {
|
|
94
|
+
const { run_setup } = await Promise.resolve().then(() => __importStar(require('./setup')));
|
|
95
|
+
await run_setup({
|
|
96
|
+
skip_mcp: options.skipMcp === true,
|
|
97
|
+
skip_instructions: options.skipInstructions === true,
|
|
98
|
+
url: options.url
|
|
99
|
+
});
|
|
100
|
+
})().catch((error) => {
|
|
101
|
+
console.error(error);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAEA,iEAAiE;AACjE,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ,yCAAoC;AACpC,yDAA8E;AAC9E,uCAAmD;AAEnD,mBAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC;KACpC,WAAW,CAAC,0DAA0D,CAAC,CAAC;AAE7E,mBAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,sCAAsC,CAAC,CAAC;AAC9E,mBAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,qDAAqD,CAAC,CAAC;AACzF,mBAAO,CAAC,MAAM,CAAC,YAAY,EAAE,qCAAqC,CAAC,CAAC;AACpE,mBAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,uEAAuE,CAAC,CAAC;AAC/G,mBAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,MAAM,OAAO,GAAG,mBAAO,CAAC,IAAI,EAAE,CAAC;AAE/B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IACvB,qEAAqE;IACrE,wEAAwE;IACxE,yBAAyB;IACzB,CAAC,KAAK,IAAI,EAAE;QACR,IAAI,QAA4B,CAAC;QAEjC,IAAI,CAAC;YACD,QAAQ,GAAG,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAA,wBAAkB,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACvF,CAAC;QAAC,MAAM,CAAC;YACL,0DAA0D;QAC9D,CAAC;QAED,IAAI,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAA,mCAAoB,EAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAErE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,CAAC,GAAG,CAAC,IAAA,6BAAc,EAAC,MAAM,CAAC,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;KAAM,CAAC;IACJ,yEAAyE;IACzE,uEAAuE;IACvE,wEAAwE;IACxE,CAAC,KAAK,IAAI,EAAE;QACR,MAAM,EAAE,SAAS,EAAE,GAAG,wDAAa,SAAS,GAAC,CAAC;QAE9C,MAAM,SAAS,CAAC;YACZ,QAAQ,EAAE,OAAO,CAAC,OAAO,KAAK,IAAI;YAClC,iBAAiB,EAAE,OAAO,CAAC,gBAAgB,KAAK,IAAI;YACpD,GAAG,EAAE,OAAO,CAAC,GAAG;SACnB,CAAC,CAAC;IACP,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAU,EAAE,EAAE;QACtB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flags that pre-decide (and therefore remove) interactive choices
|
|
3
|
+
*/
|
|
4
|
+
export interface SetupFlags {
|
|
5
|
+
skip_mcp?: boolean;
|
|
6
|
+
skip_instructions?: boolean;
|
|
7
|
+
/** pre-answers the server question; the base URL prompt is skipped */
|
|
8
|
+
url?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Runs the interactive setup flow: scope, harness, and component selection,
|
|
12
|
+
* nram server details, authentication choice, and the per-harness
|
|
13
|
+
* configurators
|
|
14
|
+
*
|
|
15
|
+
* @param flags component choices pre-decided on the command line
|
|
16
|
+
*/
|
|
17
|
+
export declare const run_setup: (flags?: SetupFlags) => Promise<void>;
|
package/dist/setup.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026, Brandon Lehmann <brandonlehmann@gmail.com>
|
|
3
|
+
//
|
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
// in the Software without restriction, including without limitation the rights
|
|
7
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
// furnished to do so, subject to the following conditions:
|
|
10
|
+
//
|
|
11
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
// copies or substantial portions of the Software.
|
|
13
|
+
//
|
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
// SOFTWARE.
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.run_setup = void 0;
|
|
26
|
+
const prompts_1 = require("@clack/prompts");
|
|
27
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
28
|
+
const harnesses_1 = require("./helpers/harnesses");
|
|
29
|
+
const instructions_1 = require("./helpers/instructions");
|
|
30
|
+
const url_1 = require("./helpers/url");
|
|
31
|
+
const types_1 = require("./types");
|
|
32
|
+
/**
|
|
33
|
+
* Unwraps a clack prompt result, exiting cleanly if the user cancelled
|
|
34
|
+
*
|
|
35
|
+
* @param value the prompt result
|
|
36
|
+
*/
|
|
37
|
+
const guard = (value) => {
|
|
38
|
+
if ((0, prompts_1.isCancel)(value)) {
|
|
39
|
+
(0, prompts_1.cancel)('Setup aborted');
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Asks whether to continue past a failed verification, aborting unless the
|
|
46
|
+
* user explicitly opts in
|
|
47
|
+
*
|
|
48
|
+
* @param message the confirmation message
|
|
49
|
+
*/
|
|
50
|
+
const confirm_or_abort = async (message) => {
|
|
51
|
+
const proceed = guard(await (0, prompts_1.confirm)({ message, initialValue: false }));
|
|
52
|
+
if (!proceed) {
|
|
53
|
+
(0, prompts_1.cancel)('Setup aborted');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const KIND_COLORS = {
|
|
58
|
+
written: chalk_1.default.green,
|
|
59
|
+
updated: chalk_1.default.cyan,
|
|
60
|
+
skipped: chalk_1.default.yellow,
|
|
61
|
+
manual: chalk_1.default.magenta,
|
|
62
|
+
failed: chalk_1.default.red
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Renders a configurator's results beneath its harness label
|
|
66
|
+
*
|
|
67
|
+
* @param label the harness label
|
|
68
|
+
* @param results the configurator results
|
|
69
|
+
*/
|
|
70
|
+
const render_results = (label, results) => {
|
|
71
|
+
const lines = results.map(result => `${KIND_COLORS[result.kind](result.kind.padEnd(7))} ${result.action}: ${result.detail}`);
|
|
72
|
+
prompts_1.log.message(`${chalk_1.default.bold(label)}\n${lines.join('\n')}`);
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Runs the interactive setup flow: scope, harness, and component selection,
|
|
76
|
+
* nram server details, authentication choice, and the per-harness
|
|
77
|
+
* configurators
|
|
78
|
+
*
|
|
79
|
+
* @param flags component choices pre-decided on the command line
|
|
80
|
+
*/
|
|
81
|
+
const run_setup = async (flags = {}) => {
|
|
82
|
+
if (flags.skip_mcp && flags.skip_instructions) {
|
|
83
|
+
console.error('Nothing to configure: both --skip-mcp and --skip-instructions were given.');
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
// Validate a command-line URL before any prompts so a typo fails fast
|
|
87
|
+
// instead of after the user has answered every question
|
|
88
|
+
let preset_url;
|
|
89
|
+
if (flags.url !== undefined) {
|
|
90
|
+
try {
|
|
91
|
+
preset_url = (0, url_1.normalize_base_url)(flags.url);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error(`Invalid --url "${flags.url}": ${error.message}`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
(0, prompts_1.intro)(chalk_1.default.bold('@nram-ai/setup-agents'));
|
|
99
|
+
const scope = guard(await (0, prompts_1.select)({
|
|
100
|
+
message: 'Configure at which level?',
|
|
101
|
+
options: [
|
|
102
|
+
{ value: types_1.Scope.USER, label: 'User level', hint: 'your account-wide configuration' },
|
|
103
|
+
{ value: types_1.Scope.PROJECT, label: 'Project level', hint: 'this directory, shared via the repository' }
|
|
104
|
+
],
|
|
105
|
+
initialValue: types_1.Scope.USER
|
|
106
|
+
}));
|
|
107
|
+
const detected = new Map(harnesses_1.HARNESSES.map(descriptor => [descriptor.harness, descriptor.detected(scope)]));
|
|
108
|
+
if (scope === types_1.Scope.USER && ![...detected.values()].some(found => found)) {
|
|
109
|
+
(0, prompts_1.cancel)('No supported harnesses were detected at the user level. ' +
|
|
110
|
+
`Install one (${harnesses_1.HARNESSES.map(descriptor => descriptor.label).join(', ')}) ` +
|
|
111
|
+
'or rerun with project-level scope.');
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
const selected = guard(await (0, prompts_1.multiselect)({
|
|
115
|
+
message: 'Which tools would you like to configure to work with nram?',
|
|
116
|
+
options: harnesses_1.HARNESSES.map(descriptor => ({
|
|
117
|
+
value: descriptor.harness,
|
|
118
|
+
label: descriptor.label,
|
|
119
|
+
hint: detected.get(descriptor.harness)
|
|
120
|
+
? 'detected'
|
|
121
|
+
: scope === types_1.Scope.PROJECT ? 'not detected here; can be configured anyway' : 'not detected',
|
|
122
|
+
disabled: scope === types_1.Scope.USER && !detected.get(descriptor.harness)
|
|
123
|
+
})),
|
|
124
|
+
initialValues: harnesses_1.HARNESSES.filter(descriptor => detected.get(descriptor.harness))
|
|
125
|
+
.map(descriptor => descriptor.harness),
|
|
126
|
+
required: true
|
|
127
|
+
}));
|
|
128
|
+
const available = [];
|
|
129
|
+
if (!flags.skip_mcp) {
|
|
130
|
+
available.push({
|
|
131
|
+
value: 'mcp',
|
|
132
|
+
label: 'MCP server connection',
|
|
133
|
+
hint: 'register nram as an MCP server'
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (!flags.skip_instructions) {
|
|
137
|
+
available.push({
|
|
138
|
+
value: 'instructions',
|
|
139
|
+
label: 'Agent instructions',
|
|
140
|
+
hint: 'SessionStart hook, AGENTS.md, or rules file'
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
const components = available.length === 1
|
|
144
|
+
? available.map(option => option.value)
|
|
145
|
+
: guard(await (0, prompts_1.multiselect)({
|
|
146
|
+
message: 'What should be configured?',
|
|
147
|
+
options: available,
|
|
148
|
+
initialValues: available.map(option => option.value),
|
|
149
|
+
required: true
|
|
150
|
+
}));
|
|
151
|
+
const wants_mcp = components.includes('mcp');
|
|
152
|
+
const wants_instructions = components.includes('instructions');
|
|
153
|
+
// The base URL now serves both components: the MCP endpoint derives from
|
|
154
|
+
// it, and the canonical agent instructions are fetched from it
|
|
155
|
+
let base_url;
|
|
156
|
+
if (preset_url !== undefined) {
|
|
157
|
+
base_url = preset_url;
|
|
158
|
+
prompts_1.log.info(`Using the nram server at ${base_url} (provided via --url)`);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
base_url = (0, url_1.normalize_base_url)(guard(await (0, prompts_1.text)({
|
|
162
|
+
message: 'What is the base URL of your nram server?',
|
|
163
|
+
initialValue: 'http://localhost:8674',
|
|
164
|
+
validate: (value) => {
|
|
165
|
+
try {
|
|
166
|
+
(0, url_1.normalize_base_url)(value ?? '');
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
return error.message;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
})));
|
|
173
|
+
}
|
|
174
|
+
// The URL is baked into hook commands and used for the instructions
|
|
175
|
+
// fetch even without MCP, so verify it on every run; a typo'd URL must
|
|
176
|
+
// hit this gate rather than quietly riding the fallback chain
|
|
177
|
+
const health = (0, prompts_1.spinner)();
|
|
178
|
+
health.start(`Checking ${base_url}/v1/health`);
|
|
179
|
+
let healthy = false;
|
|
180
|
+
try {
|
|
181
|
+
const response = await fetch(`${base_url}/v1/health`, { signal: AbortSignal.timeout(7_000) });
|
|
182
|
+
healthy = response.ok;
|
|
183
|
+
health.stop(healthy
|
|
184
|
+
? `nram is reachable at ${base_url}`
|
|
185
|
+
: `nram responded with HTTP ${response.status} at ${base_url}/v1/health`);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
health.stop(`Could not reach ${base_url}/v1/health: ${error.message}`);
|
|
189
|
+
}
|
|
190
|
+
if (!healthy) {
|
|
191
|
+
await confirm_or_abort('The nram server could not be verified. Continue writing configuration anyway?');
|
|
192
|
+
}
|
|
193
|
+
let mcp_endpoint;
|
|
194
|
+
let api_key;
|
|
195
|
+
if (wants_mcp) {
|
|
196
|
+
mcp_endpoint = (0, url_1.mcp_url)(base_url);
|
|
197
|
+
const auth = guard(await (0, prompts_1.select)({
|
|
198
|
+
message: 'How should your tools authenticate to nram?',
|
|
199
|
+
options: [
|
|
200
|
+
{ value: 'oauth', label: 'OAuth', hint: 'recommended; tools negotiate automatically via discovery' },
|
|
201
|
+
{ value: 'api-key', label: 'API key', hint: 'a nram_k_ key used as a Bearer token' }
|
|
202
|
+
],
|
|
203
|
+
initialValue: 'oauth'
|
|
204
|
+
}));
|
|
205
|
+
if (auth === 'api-key') {
|
|
206
|
+
api_key = guard(await (0, prompts_1.password)({
|
|
207
|
+
message: 'Paste your nram API key',
|
|
208
|
+
validate: (value) => {
|
|
209
|
+
if (!/^nram_k_[0-9a-zA-Z]+$/.test(value ?? '')) {
|
|
210
|
+
return 'That does not look like an nram API key (expected the nram_k_ prefix)';
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}));
|
|
214
|
+
const check = (0, prompts_1.spinner)();
|
|
215
|
+
check.start('Verifying the API key');
|
|
216
|
+
let verified = false;
|
|
217
|
+
try {
|
|
218
|
+
const response = await fetch(`${base_url}/userinfo`, {
|
|
219
|
+
headers: { Authorization: `Bearer ${api_key}` },
|
|
220
|
+
signal: AbortSignal.timeout(7_000)
|
|
221
|
+
});
|
|
222
|
+
verified = response.ok;
|
|
223
|
+
check.stop(verified ? 'API key verified' : `The key was rejected (HTTP ${response.status})`);
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
check.stop(`Could not verify the API key: ${error.message}`);
|
|
227
|
+
}
|
|
228
|
+
if (!verified) {
|
|
229
|
+
await confirm_or_abort('The API key could not be verified. Continue anyway?');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
let instructions;
|
|
234
|
+
if (wants_instructions) {
|
|
235
|
+
const fetching = (0, prompts_1.spinner)();
|
|
236
|
+
fetching.start(`Fetching the canonical agent instructions from ${base_url}`);
|
|
237
|
+
const [full, condensed] = await Promise.all([
|
|
238
|
+
(0, instructions_1.resolve_instructions)(base_url, 'full', 7_000),
|
|
239
|
+
(0, instructions_1.resolve_instructions)(base_url, 'condensed', 7_000)
|
|
240
|
+
]);
|
|
241
|
+
instructions = { full: full.text, condensed: condensed.text };
|
|
242
|
+
if (full.source === 'server' && condensed.source === 'server') {
|
|
243
|
+
fetching.stop(`Canonical agent instructions fetched from ${base_url}`);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
fetching.stop(`The canonical agent instructions could not be fetched from ${base_url}`);
|
|
247
|
+
const describe = {
|
|
248
|
+
server: 'the server',
|
|
249
|
+
cache: 'the last copy cached on this machine',
|
|
250
|
+
github: 'the fallback copy on GitHub',
|
|
251
|
+
builtin: 'a built-in notice (the canonical text was unreachable everywhere)'
|
|
252
|
+
};
|
|
253
|
+
prompts_1.log.warn(full.source === condensed.source
|
|
254
|
+
? `Using ${describe[full.source]} for the agent instructions and the condensed rules.`
|
|
255
|
+
: `Using ${describe[full.source]} for the agent instructions and ` +
|
|
256
|
+
`${describe[condensed.source]} for the condensed rules.`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const setup = { scope, base_url, mcp_url: mcp_endpoint, api_key, instructions };
|
|
260
|
+
let failures = 0;
|
|
261
|
+
let changes = 0;
|
|
262
|
+
for (const descriptor of harnesses_1.HARNESSES.filter(descriptor => selected.includes(descriptor.harness))) {
|
|
263
|
+
const progress = (0, prompts_1.spinner)();
|
|
264
|
+
progress.start(`Configuring ${descriptor.label}`);
|
|
265
|
+
try {
|
|
266
|
+
const results = await descriptor.configure(setup);
|
|
267
|
+
const written = results.filter(result => result.kind === 'written' || result.kind === 'updated').length;
|
|
268
|
+
progress.stop(written !== 0 ? `${descriptor.label} configured` : `${descriptor.label}: no changes`);
|
|
269
|
+
failures += results.filter(result => result.kind === 'failed').length;
|
|
270
|
+
changes += written;
|
|
271
|
+
render_results(descriptor.label, results);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
progress.stop(`${descriptor.label} failed: ${error.message}`);
|
|
275
|
+
failures++;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
let done_message;
|
|
279
|
+
if (failures !== 0) {
|
|
280
|
+
done_message = chalk_1.default.red('Completed with failures; review the output above.');
|
|
281
|
+
}
|
|
282
|
+
else if (changes === 0) {
|
|
283
|
+
done_message = 'No changes were made; everything selected was already configured or not applicable.';
|
|
284
|
+
}
|
|
285
|
+
else if (wants_mcp) {
|
|
286
|
+
done_message = 'Done. Restart your agent sessions to pick up the changes. ' +
|
|
287
|
+
'OAuth-capable tools will prompt to authenticate on first use (Claude Code: run /mcp).';
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
done_message = 'Done. Restart your agent sessions to pick up the changes.';
|
|
291
|
+
}
|
|
292
|
+
(0, prompts_1.outro)(done_message);
|
|
293
|
+
process.exitCode = failures === 0 ? 0 : 1;
|
|
294
|
+
};
|
|
295
|
+
exports.run_setup = run_setup;
|
|
296
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export declare enum Harness {
|
|
2
|
+
ANTHROPIC_CLAUDE_CODE = 1,
|
|
3
|
+
OPENAI_CODEX = 2,
|
|
4
|
+
OPENCODE = 3,
|
|
5
|
+
CURSOR = 4,
|
|
6
|
+
AMP = 5,
|
|
7
|
+
OPENCLAW = 6,
|
|
8
|
+
GITHUB_COPILOT_CLI = 7,
|
|
9
|
+
FACTORY_DROID = 8,
|
|
10
|
+
HERMES = 9,
|
|
11
|
+
JETBRAINS_JUNIE = 10,
|
|
12
|
+
KILO_CODE = 11,
|
|
13
|
+
KIRO = 12,
|
|
14
|
+
PI = 13,
|
|
15
|
+
TRAE = 14,
|
|
16
|
+
VSCODE = 15,
|
|
17
|
+
GOOGLE_ANTIGRAVITY = 16,
|
|
18
|
+
KIMI_CODE = 17,
|
|
19
|
+
MISTRAL_VIBE = 18,
|
|
20
|
+
XAI_GROK_BUILD = 19
|
|
21
|
+
}
|
|
22
|
+
export declare enum Scope {
|
|
23
|
+
USER = 1,
|
|
24
|
+
PROJECT = 2
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The options collected from the user that drive every harness configurator
|
|
28
|
+
*/
|
|
29
|
+
export interface SetupOptions {
|
|
30
|
+
scope: Scope;
|
|
31
|
+
/** The normalized nram base URL; embedded into SessionStart hook commands */
|
|
32
|
+
base_url: string;
|
|
33
|
+
/** The MCP endpoint URL; undefined when MCP registration was not requested */
|
|
34
|
+
mcp_url?: string;
|
|
35
|
+
/** Present only when the user chose API-key authentication */
|
|
36
|
+
api_key?: string;
|
|
37
|
+
/**
|
|
38
|
+
* The agent instructions to inject (SessionStart hook, AGENTS.md, or
|
|
39
|
+
* rules file), resolved from the server; undefined when not requested.
|
|
40
|
+
* `full` feeds AGENTS.md-style embeds, `condensed` the always-injected
|
|
41
|
+
* surfaces (rules files, steering docs)
|
|
42
|
+
*/
|
|
43
|
+
instructions?: {
|
|
44
|
+
full: string;
|
|
45
|
+
condensed: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export type ActionKind = 'written' | 'updated' | 'skipped' | 'manual' | 'failed';
|
|
49
|
+
/**
|
|
50
|
+
* The outcome of a single configuration action taken (or not taken) by a configurator
|
|
51
|
+
*/
|
|
52
|
+
export interface ActionResult {
|
|
53
|
+
/** Short action name, e.g. `MCP registration` */
|
|
54
|
+
action: string;
|
|
55
|
+
kind: ActionKind;
|
|
56
|
+
/** The file path, command, or manual instruction the user needs to see */
|
|
57
|
+
detail: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Describes a supported harness: how to detect it and how to configure it
|
|
61
|
+
*/
|
|
62
|
+
export interface HarnessDescriptor {
|
|
63
|
+
harness: Harness;
|
|
64
|
+
label: string;
|
|
65
|
+
detected: (scope: Scope) => boolean;
|
|
66
|
+
configure: (options: SetupOptions) => Promise<ActionResult[]>;
|
|
67
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026, Brandon Lehmann <brandonlehmann@gmail.com>
|
|
3
|
+
//
|
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
// in the Software without restriction, including without limitation the rights
|
|
7
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
// furnished to do so, subject to the following conditions:
|
|
10
|
+
//
|
|
11
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
// copies or substantial portions of the Software.
|
|
13
|
+
//
|
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
// SOFTWARE.
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.Scope = exports.Harness = void 0;
|
|
23
|
+
var Harness;
|
|
24
|
+
(function (Harness) {
|
|
25
|
+
Harness[Harness["ANTHROPIC_CLAUDE_CODE"] = 1] = "ANTHROPIC_CLAUDE_CODE";
|
|
26
|
+
Harness[Harness["OPENAI_CODEX"] = 2] = "OPENAI_CODEX";
|
|
27
|
+
Harness[Harness["OPENCODE"] = 3] = "OPENCODE";
|
|
28
|
+
Harness[Harness["CURSOR"] = 4] = "CURSOR";
|
|
29
|
+
Harness[Harness["AMP"] = 5] = "AMP";
|
|
30
|
+
Harness[Harness["OPENCLAW"] = 6] = "OPENCLAW";
|
|
31
|
+
Harness[Harness["GITHUB_COPILOT_CLI"] = 7] = "GITHUB_COPILOT_CLI";
|
|
32
|
+
Harness[Harness["FACTORY_DROID"] = 8] = "FACTORY_DROID";
|
|
33
|
+
Harness[Harness["HERMES"] = 9] = "HERMES";
|
|
34
|
+
Harness[Harness["JETBRAINS_JUNIE"] = 10] = "JETBRAINS_JUNIE";
|
|
35
|
+
Harness[Harness["KILO_CODE"] = 11] = "KILO_CODE";
|
|
36
|
+
Harness[Harness["KIRO"] = 12] = "KIRO";
|
|
37
|
+
Harness[Harness["PI"] = 13] = "PI";
|
|
38
|
+
Harness[Harness["TRAE"] = 14] = "TRAE";
|
|
39
|
+
Harness[Harness["VSCODE"] = 15] = "VSCODE";
|
|
40
|
+
Harness[Harness["GOOGLE_ANTIGRAVITY"] = 16] = "GOOGLE_ANTIGRAVITY";
|
|
41
|
+
Harness[Harness["KIMI_CODE"] = 17] = "KIMI_CODE";
|
|
42
|
+
Harness[Harness["MISTRAL_VIBE"] = 18] = "MISTRAL_VIBE";
|
|
43
|
+
Harness[Harness["XAI_GROK_BUILD"] = 19] = "XAI_GROK_BUILD";
|
|
44
|
+
})(Harness || (exports.Harness = Harness = {}));
|
|
45
|
+
var Scope;
|
|
46
|
+
(function (Scope) {
|
|
47
|
+
Scope[Scope["USER"] = 1] = "USER";
|
|
48
|
+
Scope[Scope["PROJECT"] = 2] = "PROJECT";
|
|
49
|
+
})(Scope || (exports.Scope = Scope = {}));
|
|
50
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,iEAAiE;AACjE,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAEZ,IAAY,OAoBX;AApBD,WAAY,OAAO;IACf,uEAAyB,CAAA;IACzB,qDAAgB,CAAA;IAChB,6CAAY,CAAA;IACZ,yCAAU,CAAA;IACV,mCAAO,CAAA;IACP,6CAAY,CAAA;IACZ,iEAAsB,CAAA;IACtB,uDAAiB,CAAA;IACjB,yCAAU,CAAA;IACV,4DAAoB,CAAA;IACpB,gDAAc,CAAA;IACd,sCAAS,CAAA;IACT,kCAAO,CAAA;IACP,sCAAS,CAAA;IACT,0CAAW,CAAA;IACX,kEAAuB,CAAA;IACvB,gDAAc,CAAA;IACd,sDAAiB,CAAA;IACjB,0DAAmB,CAAA;AACvB,CAAC,EApBW,OAAO,uBAAP,OAAO,QAoBlB;AAED,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,iCAAQ,CAAA;IACR,uCAAW,CAAA;AACf,CAAC,EAHW,KAAK,qBAAL,KAAK,QAGhB"}
|