@nomai/nomai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,145 @@
1
+ import { n as __require, t as __commonJSMin } from "./rolldown-runtime-C7HZzL1F.mjs";
2
+ //#region node_modules/@vercel/detect-agent/dist/index.js
3
+ var require_dist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
17
+ get: () => from[key],
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ return to;
22
+ };
23
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
+ var src_exports = {};
25
+ __export(src_exports, {
26
+ KNOWN_AGENTS: () => KNOWN_AGENTS,
27
+ determineAgent: () => determineAgent
28
+ });
29
+ module.exports = __toCommonJS(src_exports);
30
+ var import_promises = __require("node:fs/promises");
31
+ var import_node_fs = __require("node:fs");
32
+ const DEVIN_LOCAL_PATH = "/opt/.devin";
33
+ const CURSOR = "cursor";
34
+ const CURSOR_CLI = "cursor-cli";
35
+ const CLAUDE = "claude";
36
+ const COWORK = "cowork";
37
+ const DEVIN = "devin";
38
+ const REPLIT = "replit";
39
+ const GEMINI = "gemini";
40
+ const CODEX = "codex";
41
+ const ANTIGRAVITY = "antigravity";
42
+ const AUGMENT_CLI = "augment-cli";
43
+ const OPENCODE = "opencode";
44
+ const GITHUB_COPILOT = "github-copilot";
45
+ const GITHUB_COPILOT_CLI = "github-copilot-cli";
46
+ const V0 = "v0";
47
+ const KNOWN_AGENTS = {
48
+ CURSOR,
49
+ CURSOR_CLI,
50
+ CLAUDE,
51
+ COWORK,
52
+ DEVIN,
53
+ REPLIT,
54
+ GEMINI,
55
+ CODEX,
56
+ ANTIGRAVITY,
57
+ AUGMENT_CLI,
58
+ OPENCODE,
59
+ GITHUB_COPILOT,
60
+ V0
61
+ };
62
+ async function determineAgent() {
63
+ if (process.env.AI_AGENT) {
64
+ const name = process.env.AI_AGENT.trim();
65
+ if (name) {
66
+ if (name === GITHUB_COPILOT || name === GITHUB_COPILOT_CLI) return {
67
+ isAgent: true,
68
+ agent: { name: GITHUB_COPILOT }
69
+ };
70
+ if (name === V0) return {
71
+ isAgent: true,
72
+ agent: { name: V0 }
73
+ };
74
+ return {
75
+ isAgent: true,
76
+ agent: { name }
77
+ };
78
+ }
79
+ }
80
+ if (process.env.CURSOR_TRACE_ID) return {
81
+ isAgent: true,
82
+ agent: { name: CURSOR }
83
+ };
84
+ if (process.env.CURSOR_AGENT || process.env.CURSOR_EXTENSION_HOST_ROLE === "agent-exec") return {
85
+ isAgent: true,
86
+ agent: { name: CURSOR_CLI }
87
+ };
88
+ if (process.env.GEMINI_CLI) return {
89
+ isAgent: true,
90
+ agent: { name: GEMINI }
91
+ };
92
+ if (process.env.CODEX_SANDBOX || process.env.CODEX_CI || process.env.CODEX_THREAD_ID) return {
93
+ isAgent: true,
94
+ agent: { name: CODEX }
95
+ };
96
+ if (process.env.ANTIGRAVITY_AGENT) return {
97
+ isAgent: true,
98
+ agent: { name: ANTIGRAVITY }
99
+ };
100
+ if (process.env.AUGMENT_AGENT) return {
101
+ isAgent: true,
102
+ agent: { name: AUGMENT_CLI }
103
+ };
104
+ if (process.env.OPENCODE_CLIENT) return {
105
+ isAgent: true,
106
+ agent: { name: OPENCODE }
107
+ };
108
+ if (process.env.CLAUDECODE || process.env.CLAUDE_CODE) {
109
+ if (process.env.CLAUDE_CODE_IS_COWORK) return {
110
+ isAgent: true,
111
+ agent: { name: COWORK }
112
+ };
113
+ return {
114
+ isAgent: true,
115
+ agent: { name: CLAUDE }
116
+ };
117
+ }
118
+ if (process.env.REPL_ID) return {
119
+ isAgent: true,
120
+ agent: { name: REPLIT }
121
+ };
122
+ if (process.env.COPILOT_MODEL || process.env.COPILOT_ALLOW_ALL || process.env.COPILOT_GITHUB_TOKEN) return {
123
+ isAgent: true,
124
+ agent: { name: GITHUB_COPILOT }
125
+ };
126
+ try {
127
+ await (0, import_promises.access)(DEVIN_LOCAL_PATH, import_node_fs.constants.F_OK);
128
+ return {
129
+ isAgent: true,
130
+ agent: { name: DEVIN }
131
+ };
132
+ } catch (_error) {}
133
+ return {
134
+ isAgent: false,
135
+ agent: void 0
136
+ };
137
+ }
138
+ 0 && (module.exports = {
139
+ KNOWN_AGENTS,
140
+ determineAgent
141
+ });
142
+ }));
143
+ //#endregion
144
+ export default require_dist();
145
+ export {};
@@ -0,0 +1,226 @@
1
+ //#region src/core/types.d.ts
2
+ /**
3
+ * Single source of truth for the types shared across the Nomai CLI.
4
+ *
5
+ * Design rule: ambient state (cwd, homedir) is injected through contexts and
6
+ * never read below the CLI layer, so every module is testable against temp dirs.
7
+ */
8
+ type InstallScope = "project" | "global";
9
+ /** Ambient paths, resolved once at the CLI layer and passed down. */
10
+ interface ResolveContext {
11
+ /** The project the user runs nomai in (cwd or --dir override). */
12
+ projectDir: string;
13
+ /** os.homedir() in production, a temp dir in tests. */
14
+ homeDir: string;
15
+ }
16
+ /** One file of the payload, path relative to the harness install dir. */
17
+ interface PayloadFile {
18
+ /** e.g. "skills/nomai/SKILL.md" */
19
+ relPath: string;
20
+ contents: Buffer;
21
+ }
22
+ /**
23
+ * Where the installable payload comes from. The default implementation
24
+ * downloads the Nomai GitHub repo; a local checkout is used for dev/tests.
25
+ * A future remote registry plugs in here.
26
+ */
27
+ interface PayloadSource {
28
+ /** Human-readable origin recorded in the manifest, e.g. "owner/nomai#main". */
29
+ readonly description: string;
30
+ /** Canonical shared payload (contents of payload/shared/). */
31
+ readSharedFiles(): Promise<PayloadFile[]>;
32
+ /** Per-harness overlay (contents of payload/<harnessId>/), [] if none. */
33
+ readHarnessOverlay(harnessId: string): Promise<PayloadFile[]>;
34
+ /** Release temp resources. Safe to call more than once. */
35
+ dispose(): Promise<void>;
36
+ }
37
+ interface TransformContext extends ResolveContext {
38
+ scope: InstallScope;
39
+ nomaiVersion: string;
40
+ }
41
+ interface OperationContext extends ResolveContext {
42
+ scope: InstallScope;
43
+ /** Required for install/update. Uninstall and status work offline from the manifest. */
44
+ payload?: PayloadSource;
45
+ nomaiVersion: string;
46
+ dryRun: boolean;
47
+ /** Overrides the keep-user-modified-files protection on delete paths. */
48
+ force: boolean;
49
+ }
50
+ interface InstallResult {
51
+ installDir: string;
52
+ filesWritten: string[];
53
+ filesRemoved: string[];
54
+ /** True when the install was already up to date and nothing changed. */
55
+ skipped: boolean;
56
+ }
57
+ interface UninstallResult {
58
+ installDir: string;
59
+ /** True when there was no nomai manifest at this target. */
60
+ notInstalled: boolean;
61
+ filesRemoved: string[];
62
+ /** User-modified files kept in place (pass --force to remove them too). */
63
+ filesKept: string[];
64
+ }
65
+ interface HarnessStatus {
66
+ harnessId: string;
67
+ scope: InstallScope;
68
+ installDir: string;
69
+ /** Harness present at this scope (its config dir exists). */
70
+ detected: boolean;
71
+ /** Nomai manifest found at this target. */
72
+ installed: boolean;
73
+ installedVersion?: string;
74
+ installedAt?: string;
75
+ /** Manifest-listed files whose on-disk content no longer matches. */
76
+ modifiedFiles: string[];
77
+ /** Manifest-listed files that no longer exist. */
78
+ missingFiles: string[];
79
+ }
80
+ /**
81
+ * One AI coding harness (Claude Code, Codex, Cursor, ...).
82
+ *
83
+ * Create adapters with defineHarness() — it fills every method with defaults
84
+ * that delegate to the generic engine, so a typical adapter is ~5 lines.
85
+ * Every method stays overridable for harnesses that need custom behavior
86
+ * (e.g. merging hooks into a settings.json instead of copying files).
87
+ */
88
+ interface HarnessAdapter {
89
+ /** Stable machine id used in --harness, manifests, and payload/<id>/. */
90
+ readonly id: string;
91
+ /** Name shown in the wizard, e.g. "Claude Code". */
92
+ readonly displayName: string;
93
+ /** The harness config dir name, e.g. ".claude". */
94
+ readonly configDirName: string;
95
+ /** Is this harness in use in the project? Default: <projectDir>/<configDirName> exists. */
96
+ detectProject(projectDir: string): Promise<boolean>;
97
+ /** Is this harness installed for the user? Default: <homeDir>/<configDirName> exists. */
98
+ detectGlobal(homeDir: string): Promise<boolean>;
99
+ /** Directory nomai writes into for a scope, e.g. <projectDir>/.claude. */
100
+ resolveInstallDir(scope: InstallScope, ctx: ResolveContext): string;
101
+ /**
102
+ * Per-harness compilation hook. Receives the merged payload (shared +
103
+ * harness overlay, overlay wins) and returns the files to write.
104
+ * Default: identity.
105
+ */
106
+ transformPayload(files: PayloadFile[], ctx: TransformContext): Promise<PayloadFile[]>;
107
+ install(ctx: OperationContext): Promise<InstallResult>;
108
+ uninstall(ctx: OperationContext): Promise<UninstallResult>;
109
+ status(ctx: OperationContext): Promise<HarnessStatus>;
110
+ }
111
+ interface DetectionResult {
112
+ harnessId: string;
113
+ project: boolean;
114
+ global: boolean;
115
+ }
116
+ interface DetectionReport {
117
+ results: DetectionResult[];
118
+ /** Ids detected at either scope — preseeds the wizard multiselect. */
119
+ detectedIds: string[];
120
+ /** Ids detected at project scope — drives the default scope answer. */
121
+ projectDetectedIds: string[];
122
+ }
123
+ /** Resolved answers of the install wizard (or of its flag-based bypass). */
124
+ interface InstallPlan {
125
+ harnessIds: string[];
126
+ scope: InstallScope;
127
+ }
128
+ interface ManifestFileEntry {
129
+ /** Relative to the install dir, posix separators. */
130
+ path: string;
131
+ sha256: string;
132
+ }
133
+ /** Receipt written next to the installed files; drives idempotency, update, and clean uninstall. */
134
+ interface Manifest {
135
+ schemaVersion: 1;
136
+ nomaiVersion: string;
137
+ /** PayloadSource description this install came from. */
138
+ source: string;
139
+ harness: string;
140
+ scope: InstallScope;
141
+ installedAt: string;
142
+ files: ManifestFileEntry[];
143
+ }
144
+ //#endregion
145
+ //#region src/harnesses/define.d.ts
146
+ interface HarnessConfig {
147
+ /** Stable machine id, e.g. "claude-code". */
148
+ id: string;
149
+ /** Name shown in the wizard, e.g. "Claude Code". */
150
+ displayName: string;
151
+ /** The harness config dir name, e.g. ".claude". */
152
+ configDirName: string;
153
+ /** Optional overrides — every default delegates to the generic engine. */
154
+ detectProject?: HarnessAdapter["detectProject"];
155
+ detectGlobal?: HarnessAdapter["detectGlobal"];
156
+ resolveInstallDir?: HarnessAdapter["resolveInstallDir"];
157
+ transformPayload?: HarnessAdapter["transformPayload"];
158
+ install?: HarnessAdapter["install"];
159
+ uninstall?: HarnessAdapter["uninstall"];
160
+ status?: HarnessAdapter["status"];
161
+ }
162
+ /**
163
+ * Build a HarnessAdapter from declarative config. A typical adapter is:
164
+ *
165
+ * export const claudeCode = defineHarness({
166
+ * id: "claude-code",
167
+ * displayName: "Claude Code",
168
+ * configDirName: ".claude",
169
+ * });
170
+ *
171
+ * Harnesses that need per-harness compilation override transformPayload;
172
+ * harnesses with entirely custom mechanics (e.g. settings.json merges for
173
+ * hooks) can override install/uninstall/status wholesale.
174
+ */
175
+ declare function defineHarness(config: HarnessConfig): HarnessAdapter;
176
+ //#endregion
177
+ //#region src/core/registry.d.ts
178
+ declare function listHarnesses(): HarnessAdapter[];
179
+ declare function getHarness(id: string): HarnessAdapter;
180
+ //#endregion
181
+ //#region src/core/detect.d.ts
182
+ /**
183
+ * Ask every registered harness whether it is present at project and global
184
+ * scope. The report preseeds the wizard's harness multiselect and drives
185
+ * the defaults used by --yes.
186
+ */
187
+ declare function detectHarnesses(ctx: ResolveContext): Promise<DetectionReport>;
188
+ //#endregion
189
+ //#region src/core/installer.d.ts
190
+ /**
191
+ * Generic install/uninstall/status engine shared by all harness adapters.
192
+ * defineHarness() wires adapter methods to these functions by default;
193
+ * adapters with special needs override the methods instead.
194
+ *
195
+ * This module is the only place in the codebase that writes to disk.
196
+ */
197
+ declare function installHarness(adapter: HarnessAdapter, ctx: OperationContext): Promise<InstallResult>;
198
+ declare function uninstallHarness(adapter: HarnessAdapter, ctx: OperationContext): Promise<UninstallResult>;
199
+ declare function statusHarness(adapter: HarnessAdapter, ctx: OperationContext): Promise<HarnessStatus>;
200
+ //#endregion
201
+ //#region src/core/payload.d.ts
202
+ /**
203
+ * Default payload source: the Nomai GitHub repo, fetched as a codeload
204
+ * tarball of `main` at install time (same model as BuilderIO's
205
+ * `npx @agent-native/skills`). The npm package itself ships no payload.
206
+ */
207
+ declare const DEFAULT_SOURCE = "A-MCode/nomai-installer";
208
+ interface GitHubSourceRef {
209
+ owner: string;
210
+ repo: string;
211
+ ref?: string;
212
+ }
213
+ /** Accepts "owner/repo", "owner/repo#ref", or a github.com URL (optionally /tree/<ref>). */
214
+ declare function parseGitHubSource(input: string): GitHubSourceRef | null;
215
+ /**
216
+ * Turn a --source value (or the default) into a live PayloadSource:
217
+ * an existing local path wins, otherwise a GitHub download.
218
+ */
219
+ declare function resolvePayloadSource(input?: string): Promise<PayloadSource>;
220
+ //#endregion
221
+ //#region src/core/manifest.d.ts
222
+ declare const MANIFEST_FILENAME = "nomai-manifest.json";
223
+ /** @returns null when no manifest exists; throws on a corrupt/foreign one. */
224
+ declare function readManifest(installDir: string): Promise<Manifest | null>;
225
+ //#endregion
226
+ export { DEFAULT_SOURCE, type DetectionReport, type DetectionResult, type HarnessAdapter, type HarnessConfig, type HarnessStatus, type InstallPlan, type InstallResult, type InstallScope, MANIFEST_FILENAME, type Manifest, type ManifestFileEntry, type OperationContext, type PayloadFile, type PayloadSource, type ResolveContext, type TransformContext, type UninstallResult, defineHarness, detectHarnesses, getHarness, installHarness, listHarnesses, parseGitHubSource, readManifest, resolvePayloadSource, statusHarness, uninstallHarness };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { a as getHarness, c as installHarness, d as MANIFEST_FILENAME, f as readManifest, i as detectHarnesses, l as statusHarness, n as parseGitHubSource, o as listHarnesses, r as resolvePayloadSource, s as defineHarness, t as DEFAULT_SOURCE, u as uninstallHarness } from "./payload-DdBYzrl3.mjs";
2
+ export { DEFAULT_SOURCE, MANIFEST_FILENAME, defineHarness, detectHarnesses, getHarness, installHarness, listHarnesses, parseGitHubSource, readManifest, resolvePayloadSource, statusHarness, uninstallHarness };