@enbox/gitd 0.2.0 → 0.3.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/esm/cli/agent.js +66 -11
- package/dist/esm/cli/agent.js.map +1 -1
- package/dist/esm/cli/commands/auth.js +265 -0
- package/dist/esm/cli/commands/auth.js.map +1 -0
- package/dist/esm/cli/main.js +16 -1
- package/dist/esm/cli/main.js.map +1 -1
- package/dist/esm/git-remote/credential-main.js +34 -8
- package/dist/esm/git-remote/credential-main.js.map +1 -1
- package/dist/esm/profiles/config.js +156 -0
- package/dist/esm/profiles/config.js.map +1 -0
- package/dist/types/cli/agent.d.ts +27 -4
- package/dist/types/cli/agent.d.ts.map +1 -1
- package/dist/types/cli/commands/auth.d.ts +23 -0
- package/dist/types/cli/commands/auth.d.ts.map +1 -0
- package/dist/types/git-remote/credential-main.d.ts +2 -1
- package/dist/types/git-remote/credential-main.d.ts.map +1 -1
- package/dist/types/profiles/config.d.ts +69 -0
- package/dist/types/profiles/config.d.ts.map +1 -0
- package/package.json +2 -1
- package/src/cli/agent.ts +95 -11
- package/src/cli/commands/auth.ts +290 -0
- package/src/cli/main.ts +17 -1
- package/src/git-remote/credential-main.ts +41 -8
- package/src/profiles/config.ts +188 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile configuration — persistent config at `~/.enbox/config.json`.
|
|
3
|
+
*
|
|
4
|
+
* Manages the set of named identity profiles and the default selection.
|
|
5
|
+
* This module handles reading, writing, and resolving profiles across
|
|
6
|
+
* multiple selection sources (flag, env, git config, global default).
|
|
7
|
+
*
|
|
8
|
+
* Storage layout:
|
|
9
|
+
* ~/.enbox/
|
|
10
|
+
* config.json Global config (this module)
|
|
11
|
+
* profiles/
|
|
12
|
+
* <name>/DATA/AGENT/... Per-profile Web5 agent stores
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { homedir } from 'node:os';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { spawnSync } from 'node:child_process';
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Constants
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/** Base directory for all enbox data. Override with `ENBOX_HOME`. */
|
|
24
|
+
export function enboxHome() {
|
|
25
|
+
var _a;
|
|
26
|
+
return (_a = process.env.ENBOX_HOME) !== null && _a !== void 0 ? _a : join(homedir(), '.enbox');
|
|
27
|
+
}
|
|
28
|
+
/** Path to the global config file. */
|
|
29
|
+
export function configPath() {
|
|
30
|
+
return join(enboxHome(), 'config.json');
|
|
31
|
+
}
|
|
32
|
+
/** Base directory for all profile agent data. */
|
|
33
|
+
export function profilesDir() {
|
|
34
|
+
return join(enboxHome(), 'profiles');
|
|
35
|
+
}
|
|
36
|
+
/** Path to a specific profile's agent data directory. */
|
|
37
|
+
export function profileDataPath(name) {
|
|
38
|
+
return join(profilesDir(), name, 'DATA', 'AGENT');
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Config I/O
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/** Read the global config. Returns a default if the file doesn't exist. */
|
|
44
|
+
export function readConfig() {
|
|
45
|
+
const path = configPath();
|
|
46
|
+
if (!existsSync(path)) {
|
|
47
|
+
return { version: 1, defaultProfile: '', profiles: {} };
|
|
48
|
+
}
|
|
49
|
+
const raw = readFileSync(path, 'utf-8');
|
|
50
|
+
return JSON.parse(raw);
|
|
51
|
+
}
|
|
52
|
+
/** Write the global config atomically. */
|
|
53
|
+
export function writeConfig(config) {
|
|
54
|
+
const path = configPath();
|
|
55
|
+
mkdirSync(join(path, '..'), { recursive: true });
|
|
56
|
+
writeFileSync(path, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
57
|
+
}
|
|
58
|
+
/** Add or update a profile entry in the global config. */
|
|
59
|
+
export function upsertProfile(name, entry) {
|
|
60
|
+
const config = readConfig();
|
|
61
|
+
config.profiles[name] = entry;
|
|
62
|
+
// If this is the first profile, make it the default.
|
|
63
|
+
if (!config.defaultProfile || Object.keys(config.profiles).length === 1) {
|
|
64
|
+
config.defaultProfile = name;
|
|
65
|
+
}
|
|
66
|
+
writeConfig(config);
|
|
67
|
+
}
|
|
68
|
+
/** Remove a profile entry from the global config. */
|
|
69
|
+
export function removeProfile(name) {
|
|
70
|
+
var _a;
|
|
71
|
+
const config = readConfig();
|
|
72
|
+
delete config.profiles[name];
|
|
73
|
+
// If we removed the default, pick the first remaining (or clear).
|
|
74
|
+
if (config.defaultProfile === name) {
|
|
75
|
+
const remaining = Object.keys(config.profiles);
|
|
76
|
+
config.defaultProfile = (_a = remaining[0]) !== null && _a !== void 0 ? _a : '';
|
|
77
|
+
}
|
|
78
|
+
writeConfig(config);
|
|
79
|
+
}
|
|
80
|
+
/** List all profile names. */
|
|
81
|
+
export function listProfiles() {
|
|
82
|
+
return Object.keys(readConfig().profiles);
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Profile resolution
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Resolve which profile to use.
|
|
89
|
+
*
|
|
90
|
+
* Precedence (highest to lowest):
|
|
91
|
+
* 1. `--profile <name>` flag (passed as `flagProfile`)
|
|
92
|
+
* 2. `ENBOX_PROFILE` environment variable
|
|
93
|
+
* 3. `.git/config` → `[enbox] profile = <name>`
|
|
94
|
+
* 4. `~/.enbox/config.json` → `defaultProfile`
|
|
95
|
+
* 5. First (and only) profile, if exactly one exists
|
|
96
|
+
*
|
|
97
|
+
* Returns `null` when no profile can be resolved (i.e. none exist).
|
|
98
|
+
*/
|
|
99
|
+
export function resolveProfile(flagProfile) {
|
|
100
|
+
// 1. Explicit flag.
|
|
101
|
+
if (flagProfile) {
|
|
102
|
+
return flagProfile;
|
|
103
|
+
}
|
|
104
|
+
// 2. Environment variable.
|
|
105
|
+
const envProfile = process.env.ENBOX_PROFILE;
|
|
106
|
+
if (envProfile) {
|
|
107
|
+
return envProfile;
|
|
108
|
+
}
|
|
109
|
+
// 3. Per-repo git config.
|
|
110
|
+
const gitProfile = readGitConfigProfile();
|
|
111
|
+
if (gitProfile) {
|
|
112
|
+
return gitProfile;
|
|
113
|
+
}
|
|
114
|
+
// 4. Global default.
|
|
115
|
+
const config = readConfig();
|
|
116
|
+
if (config.defaultProfile) {
|
|
117
|
+
return config.defaultProfile;
|
|
118
|
+
}
|
|
119
|
+
// 5. Single profile fallback.
|
|
120
|
+
const names = Object.keys(config.profiles);
|
|
121
|
+
if (names.length === 1) {
|
|
122
|
+
return names[0];
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Read the `[enbox] profile` setting from the current repo's `.git/config`.
|
|
128
|
+
* Returns `null` if not in a git repo or the setting is absent.
|
|
129
|
+
*/
|
|
130
|
+
function readGitConfigProfile() {
|
|
131
|
+
var _a;
|
|
132
|
+
try {
|
|
133
|
+
const result = spawnSync('git', ['config', '--local', 'enbox.profile'], {
|
|
134
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
135
|
+
timeout: 2000,
|
|
136
|
+
});
|
|
137
|
+
const value = (_a = result.stdout) === null || _a === void 0 ? void 0 : _a.toString().trim();
|
|
138
|
+
if (result.status === 0 && value) {
|
|
139
|
+
return value;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (_b) {
|
|
143
|
+
// Not in a git repo or git not available.
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Write the `[enbox] profile` setting to the current repo's `.git/config`.
|
|
149
|
+
*/
|
|
150
|
+
export function setGitConfigProfile(name) {
|
|
151
|
+
spawnSync('git', ['config', '--local', 'enbox.profile', name], {
|
|
152
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
153
|
+
timeout: 2000,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/profiles/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
* the existing vault and return a ready-to-use `TypedWeb5` instance for
|
|
7
7
|
* each protocol.
|
|
8
8
|
*
|
|
9
|
+
* Agent data is stored under the resolved profile path:
|
|
10
|
+
* `~/.enbox/profiles/<profile>/DATA/AGENT/`
|
|
11
|
+
*
|
|
9
12
|
* @module
|
|
10
13
|
*/
|
|
11
14
|
import type { TypedWeb5 } from '@enbox/api';
|
|
@@ -48,12 +51,32 @@ export type AgentContext = {
|
|
|
48
51
|
org: TypedWeb5<typeof ForgeOrgProtocol.definition, ForgeOrgSchemaMap>;
|
|
49
52
|
web5: Web5;
|
|
50
53
|
};
|
|
54
|
+
/** Options for connecting to the agent. */
|
|
55
|
+
export type ConnectOptions = {
|
|
56
|
+
/** Vault password. */
|
|
57
|
+
password: string;
|
|
58
|
+
/**
|
|
59
|
+
* Agent data path. When provided, the agent stores all data under
|
|
60
|
+
* this directory instead of the default `DATA/AGENT` relative to CWD.
|
|
61
|
+
*
|
|
62
|
+
* The profile system sets this to `~/.enbox/profiles/<name>/DATA/AGENT`.
|
|
63
|
+
*/
|
|
64
|
+
dataPath?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Optional recovery phrase (12-word BIP-39 mnemonic) for initializing
|
|
67
|
+
* a new vault. When omitted, a new phrase is generated automatically.
|
|
68
|
+
*/
|
|
69
|
+
recoveryPhrase?: string;
|
|
70
|
+
};
|
|
51
71
|
/**
|
|
52
72
|
* Connect to the local Web5 agent, initializing on first launch.
|
|
53
73
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
74
|
+
* When `dataPath` is provided, the agent's persistent data lives there.
|
|
75
|
+
* Otherwise, it falls back to `DATA/AGENT` relative to CWD (legacy).
|
|
76
|
+
*
|
|
77
|
+
* Sync is disabled — the CLI operates against the local DWN only.
|
|
57
78
|
*/
|
|
58
|
-
export declare function connectAgent(
|
|
79
|
+
export declare function connectAgent(options: ConnectOptions): Promise<AgentContext & {
|
|
80
|
+
recoveryPhrase?: string;
|
|
81
|
+
}>;
|
|
59
82
|
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/cli/agent.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/cli/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `gitd auth` — identity and profile management.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* gitd auth Show current identity info
|
|
6
|
+
* gitd auth login Create or import an identity
|
|
7
|
+
* gitd auth list List all profiles
|
|
8
|
+
* gitd auth use <profile> Set profile for current repo
|
|
9
|
+
* gitd auth use <profile> --global Set default profile
|
|
10
|
+
* gitd auth export [profile] Export portable identity
|
|
11
|
+
* gitd auth import Import from recovery phrase
|
|
12
|
+
* gitd auth logout [profile] Remove a profile
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import type { AgentContext } from '../agent.js';
|
|
17
|
+
/**
|
|
18
|
+
* The auth command can run without a pre-existing AgentContext (for `login`,
|
|
19
|
+
* `list`), but some sub-commands need one (for `export`). We accept
|
|
20
|
+
* ctx as optional and connect lazily when needed.
|
|
21
|
+
*/
|
|
22
|
+
export declare function authCommand(ctx: AgentContext | null, args: string[]): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoBhD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzF"}
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
* helper = /path/to/git-remote-did-credential
|
|
17
17
|
*
|
|
18
18
|
* Environment:
|
|
19
|
-
* GITD_PASSWORD
|
|
19
|
+
* GITD_PASSWORD — vault password for the local agent
|
|
20
|
+
* ENBOX_PROFILE — (optional) profile name override
|
|
20
21
|
*
|
|
21
22
|
* @module
|
|
22
23
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-main.d.ts","sourceRoot":"","sources":["../../../src/git-remote/credential-main.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"credential-main.d.ts","sourceRoot":"","sources":["../../../src/git-remote/credential-main.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile configuration — persistent config at `~/.enbox/config.json`.
|
|
3
|
+
*
|
|
4
|
+
* Manages the set of named identity profiles and the default selection.
|
|
5
|
+
* This module handles reading, writing, and resolving profiles across
|
|
6
|
+
* multiple selection sources (flag, env, git config, global default).
|
|
7
|
+
*
|
|
8
|
+
* Storage layout:
|
|
9
|
+
* ~/.enbox/
|
|
10
|
+
* config.json Global config (this module)
|
|
11
|
+
* profiles/
|
|
12
|
+
* <name>/DATA/AGENT/... Per-profile Web5 agent stores
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
/** Base directory for all enbox data. Override with `ENBOX_HOME`. */
|
|
17
|
+
export declare function enboxHome(): string;
|
|
18
|
+
/** Path to the global config file. */
|
|
19
|
+
export declare function configPath(): string;
|
|
20
|
+
/** Base directory for all profile agent data. */
|
|
21
|
+
export declare function profilesDir(): string;
|
|
22
|
+
/** Path to a specific profile's agent data directory. */
|
|
23
|
+
export declare function profileDataPath(name: string): string;
|
|
24
|
+
/** Metadata about a single profile stored in config.json. */
|
|
25
|
+
export type ProfileEntry = {
|
|
26
|
+
/** Display name for the profile. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** The DID URI associated with this profile. */
|
|
29
|
+
did: string;
|
|
30
|
+
/** ISO 8601 timestamp when the profile was created. */
|
|
31
|
+
createdAt: string;
|
|
32
|
+
};
|
|
33
|
+
/** Top-level config.json shape. */
|
|
34
|
+
export type EnboxConfig = {
|
|
35
|
+
/** Schema version for forward-compatibility. */
|
|
36
|
+
version: number;
|
|
37
|
+
/** Name of the default profile. */
|
|
38
|
+
defaultProfile: string;
|
|
39
|
+
/** Map of profile name → metadata. */
|
|
40
|
+
profiles: Record<string, ProfileEntry>;
|
|
41
|
+
};
|
|
42
|
+
/** Read the global config. Returns a default if the file doesn't exist. */
|
|
43
|
+
export declare function readConfig(): EnboxConfig;
|
|
44
|
+
/** Write the global config atomically. */
|
|
45
|
+
export declare function writeConfig(config: EnboxConfig): void;
|
|
46
|
+
/** Add or update a profile entry in the global config. */
|
|
47
|
+
export declare function upsertProfile(name: string, entry: ProfileEntry): void;
|
|
48
|
+
/** Remove a profile entry from the global config. */
|
|
49
|
+
export declare function removeProfile(name: string): void;
|
|
50
|
+
/** List all profile names. */
|
|
51
|
+
export declare function listProfiles(): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Resolve which profile to use.
|
|
54
|
+
*
|
|
55
|
+
* Precedence (highest to lowest):
|
|
56
|
+
* 1. `--profile <name>` flag (passed as `flagProfile`)
|
|
57
|
+
* 2. `ENBOX_PROFILE` environment variable
|
|
58
|
+
* 3. `.git/config` → `[enbox] profile = <name>`
|
|
59
|
+
* 4. `~/.enbox/config.json` → `defaultProfile`
|
|
60
|
+
* 5. First (and only) profile, if exactly one exists
|
|
61
|
+
*
|
|
62
|
+
* Returns `null` when no profile can be resolved (i.e. none exist).
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveProfile(flagProfile?: string): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Write the `[enbox] profile` setting to the current repo's `.git/config`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function setGitConfigProfile(name: string): void;
|
|
69
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/profiles/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,sEAAsE;AACtE,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,sCAAsC;AACtC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,iDAAiD;AACjD,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAMD,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG;IACzB,oCAAoC;IACpC,IAAI,EAAG,MAAM,CAAC;IACd,gDAAgD;IAChD,GAAG,EAAG,MAAM,CAAC;IACb,uDAAuD;IACvD,SAAS,EAAG,MAAM,CAAC;CACpB,CAAC;AAEF,mCAAmC;AACnC,MAAM,MAAM,WAAW,GAAG;IACxB,gDAAgD;IAChD,OAAO,EAAG,MAAM,CAAC;IACjB,mCAAmC;IACnC,cAAc,EAAG,MAAM,CAAC;IACxB,sCAAsC;IACtC,QAAQ,EAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACzC,CAAC;AAMF,4EAA4E;AAC5E,wBAAgB,UAAU,IAAI,WAAW,CAOxC;AAED,0CAA0C;AAC1C,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAIrD;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAUrE;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAWhD;AAED,8BAA8B;AAC9B,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBlE;AAoBD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKtD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enbox/gitd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Decentralized forge (GitHub alternative) built on DWN protocols",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/index.js",
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"bun": ">=1.0.0"
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
|
+
"@clack/prompts": "^1.0.1",
|
|
94
95
|
"@enbox/api": "0.3.0",
|
|
95
96
|
"@enbox/crypto": "0.0.6",
|
|
96
97
|
"@enbox/dids": "0.0.7",
|
package/src/cli/agent.ts
CHANGED
|
@@ -6,12 +6,16 @@
|
|
|
6
6
|
* the existing vault and return a ready-to-use `TypedWeb5` instance for
|
|
7
7
|
* each protocol.
|
|
8
8
|
*
|
|
9
|
+
* Agent data is stored under the resolved profile path:
|
|
10
|
+
* `~/.enbox/profiles/<profile>/DATA/AGENT/`
|
|
11
|
+
*
|
|
9
12
|
* @module
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
import type { TypedWeb5 } from '@enbox/api';
|
|
13
16
|
|
|
14
17
|
import { Web5 } from '@enbox/api';
|
|
18
|
+
import { Web5UserAgent } from '@enbox/agent';
|
|
15
19
|
|
|
16
20
|
import type { ForgeCiSchemaMap } from '../ci.js';
|
|
17
21
|
import type { ForgeIssuesSchemaMap } from '../issues.js';
|
|
@@ -58,6 +62,24 @@ export type AgentContext = {
|
|
|
58
62
|
web5 : Web5;
|
|
59
63
|
};
|
|
60
64
|
|
|
65
|
+
/** Options for connecting to the agent. */
|
|
66
|
+
export type ConnectOptions = {
|
|
67
|
+
/** Vault password. */
|
|
68
|
+
password : string;
|
|
69
|
+
/**
|
|
70
|
+
* Agent data path. When provided, the agent stores all data under
|
|
71
|
+
* this directory instead of the default `DATA/AGENT` relative to CWD.
|
|
72
|
+
*
|
|
73
|
+
* The profile system sets this to `~/.enbox/profiles/<name>/DATA/AGENT`.
|
|
74
|
+
*/
|
|
75
|
+
dataPath? : string;
|
|
76
|
+
/**
|
|
77
|
+
* Optional recovery phrase (12-word BIP-39 mnemonic) for initializing
|
|
78
|
+
* a new vault. When omitted, a new phrase is generated automatically.
|
|
79
|
+
*/
|
|
80
|
+
recoveryPhrase? : string;
|
|
81
|
+
};
|
|
82
|
+
|
|
61
83
|
// ---------------------------------------------------------------------------
|
|
62
84
|
// Agent bootstrap
|
|
63
85
|
// ---------------------------------------------------------------------------
|
|
@@ -65,24 +87,85 @@ export type AgentContext = {
|
|
|
65
87
|
/**
|
|
66
88
|
* Connect to the local Web5 agent, initializing on first launch.
|
|
67
89
|
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
90
|
+
* When `dataPath` is provided, the agent's persistent data lives there.
|
|
91
|
+
* Otherwise, it falls back to `DATA/AGENT` relative to CWD (legacy).
|
|
92
|
+
*
|
|
93
|
+
* Sync is disabled — the CLI operates against the local DWN only.
|
|
71
94
|
*/
|
|
72
|
-
export async function connectAgent(
|
|
73
|
-
const {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
95
|
+
export async function connectAgent(options: ConnectOptions): Promise<AgentContext & { recoveryPhrase?: string }> {
|
|
96
|
+
const { password, dataPath, recoveryPhrase: inputPhrase } = options;
|
|
97
|
+
|
|
98
|
+
let agent: Web5UserAgent;
|
|
99
|
+
let recoveryPhrase: string | undefined;
|
|
100
|
+
|
|
101
|
+
if (dataPath) {
|
|
102
|
+
// Profile-based: create agent with explicit data path.
|
|
103
|
+
agent = await Web5UserAgent.create({ dataPath });
|
|
104
|
+
|
|
105
|
+
if (await agent.firstLaunch()) {
|
|
106
|
+
recoveryPhrase = await agent.initialize({
|
|
107
|
+
password,
|
|
108
|
+
recoveryPhrase : inputPhrase,
|
|
109
|
+
dwnEndpoints : ['https://enbox-dwn.fly.dev'],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
await agent.start({ password });
|
|
113
|
+
|
|
114
|
+
// Ensure at least one identity exists.
|
|
115
|
+
const identities = await agent.identity.list();
|
|
116
|
+
let identity = identities[0];
|
|
117
|
+
if (!identity) {
|
|
118
|
+
identity = await agent.identity.create({
|
|
119
|
+
didMethod : 'dht',
|
|
120
|
+
metadata : { name: 'Default' },
|
|
121
|
+
didOptions : {
|
|
122
|
+
services: [{
|
|
123
|
+
id : 'dwn',
|
|
124
|
+
type : 'DecentralizedWebNode',
|
|
125
|
+
serviceEndpoint : ['https://enbox-dwn.fly.dev'],
|
|
126
|
+
enc : '#enc',
|
|
127
|
+
sig : '#sig',
|
|
128
|
+
}],
|
|
129
|
+
verificationMethods: [
|
|
130
|
+
{ algorithm: 'Ed25519', id: 'sig', purposes: ['assertionMethod', 'authentication'] },
|
|
131
|
+
{ algorithm: 'X25519', id: 'enc', purposes: ['keyAgreement'] },
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const result = await Web5.connect({
|
|
138
|
+
agent,
|
|
139
|
+
connectedDid : identity.did.uri,
|
|
140
|
+
sync : 'off',
|
|
141
|
+
});
|
|
77
142
|
|
|
78
|
-
|
|
143
|
+
return bindProtocols(result.web5, result.did, recoveryPhrase);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Legacy: let Web5.connect() manage the agent (uses CWD-relative path).
|
|
147
|
+
const result = await Web5.connect({ password, sync: 'off' });
|
|
148
|
+
|
|
149
|
+
if (result.recoveryPhrase) {
|
|
79
150
|
console.log('');
|
|
80
151
|
console.log(' Recovery phrase (save this — it cannot be shown again):');
|
|
81
|
-
console.log(` ${recoveryPhrase}`);
|
|
152
|
+
console.log(` ${result.recoveryPhrase}`);
|
|
82
153
|
console.log('');
|
|
83
154
|
}
|
|
84
155
|
|
|
85
|
-
|
|
156
|
+
return bindProtocols(result.web5, result.did, result.recoveryPhrase);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
// Internal helpers
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
|
|
163
|
+
/** Bind typed protocol handles and configure all protocols. */
|
|
164
|
+
async function bindProtocols(
|
|
165
|
+
web5: Web5,
|
|
166
|
+
did: string,
|
|
167
|
+
recoveryPhrase?: string,
|
|
168
|
+
): Promise<AgentContext & { recoveryPhrase?: string }> {
|
|
86
169
|
const repo = web5.using(ForgeRepoProtocol);
|
|
87
170
|
const refs = web5.using(ForgeRefsProtocol);
|
|
88
171
|
const issues = web5.using(ForgeIssuesProtocol);
|
|
@@ -113,5 +196,6 @@ export async function connectAgent(password: string): Promise<AgentContext> {
|
|
|
113
196
|
return {
|
|
114
197
|
did, repo, refs, issues, patches, ci, releases,
|
|
115
198
|
registry, social, notifications, wiki, org, web5,
|
|
199
|
+
recoveryPhrase,
|
|
116
200
|
};
|
|
117
201
|
}
|