gent-cli 14.0.0 → 20.0.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/README.md +1 -1
- package/package.json +7 -4
- package/src/commands/canonical.js +242 -0
- package/src/commands/clone.js +2 -13
- package/src/commands/pet.js +122 -98
- package/src/commands/pull.js +3 -4
- package/src/commands/push.js +4 -5
- package/src/commands/share.js +40 -15
- package/src/commands/web.js +30 -15
- package/src/index.js +70 -40
- package/src/utils/api-client.js +6 -9
- package/src/utils/attributes.js +280 -0
- package/src/utils/canonical-journal.js +122 -0
- package/src/utils/feature-support.js +92 -0
- package/src/utils/feature-support.json +210 -0
- package/src/utils/gent-ops.js +836 -0
- package/src/utils/git-config.js +606 -0
- package/src/utils/git-index.js +581 -0
- package/src/utils/git-objects.js +537 -0
- package/src/utils/ignore.js +365 -0
- package/src/utils/lockfile.js +219 -0
- package/src/utils/merge-ops.js +282 -0
- package/src/utils/migrate.js +257 -0
- package/src/utils/object-store.js +332 -36
- package/src/utils/packfile.js +812 -0
- package/src/utils/refs.js +595 -0
- package/src/utils/repository.js +533 -0
- package/src/utils/smart-http.js +195 -0
- package/src/utils/stash-ops.js +355 -0
- package/src/utils/user-config.js +10 -0
- package/src/utils/web-urls.js +125 -0
- package/src/utils/worktree.js +676 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* Web URLs - Build links into the gent web app (frontend), not the API.
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* The frontend is a SEPARATE deployment from the API. Never derive a web URL
|
|
7
|
+
* from `api.base_url` — resolve `web.base_url` (env GENT_WEB_URL > user config
|
|
8
|
+
* > built-in default) instead.
|
|
9
|
+
*
|
|
10
|
+
* CANONICAL ROUTE TREE
|
|
11
|
+
* The Next.js app currently ships two parallel repo route trees:
|
|
12
|
+
* /app/[ownerId]/[name] (older lineage)
|
|
13
|
+
* /dashboard/repository/[owner_id]/[repo_name] (frontend2 lineage)
|
|
14
|
+
*
|
|
15
|
+
* We target the /dashboard tree: it is where `/auth/login` sends users after
|
|
16
|
+
* sign-in (`router.replace(DASHBOARD_PATH.ROOT)`), it is what the dashboard
|
|
17
|
+
* sidebar links to, and its route params (`owner_id` / `repo_name`) match the
|
|
18
|
+
* values the CLI parses out of a remote URL.
|
|
19
|
+
*
|
|
20
|
+
* If that decision is reversed, change `repoPath()` below — it is the single
|
|
21
|
+
* place the shape is defined.
|
|
22
|
+
*
|
|
23
|
+
* BRANCH / COMMIT DEEP LINKS
|
|
24
|
+
* The frontend has NO addressable branch or commit target. Verified against
|
|
25
|
+
* `npx next build` (no /tree/[branch], no /commit/[sha] route in either tree)
|
|
26
|
+
* and against the page sources: the branch picker and the commit diff modal
|
|
27
|
+
* are both local `useState`, never reflected in the URL or a query param.
|
|
28
|
+
* So we do not invent a URL shape — callers surface `BRANCH_COMMIT_UNSUPPORTED`
|
|
29
|
+
* and fall back to the repo page.
|
|
30
|
+
* ============================================================================
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
const userConfig = require('./user-config');
|
|
34
|
+
|
|
35
|
+
/** Message shown when a caller asks for a branch/commit link we cannot build. */
|
|
36
|
+
const BRANCH_COMMIT_UNSUPPORTED =
|
|
37
|
+
'The gent web app has no branch or commit page yet, so this link points at the repository instead.';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the web app base URL (env > user config > default), validated and
|
|
41
|
+
* without a trailing slash.
|
|
42
|
+
*
|
|
43
|
+
* Validation is deliberate: a scheme-less value like `gent.example.com` is a
|
|
44
|
+
* realistic typo, and without a check it silently yields a relative path that
|
|
45
|
+
* looks like a link but isn't one. Fail loudly here instead — this is the
|
|
46
|
+
* single normalization point, so callers can assume a clean http(s) base.
|
|
47
|
+
*
|
|
48
|
+
* @returns {Promise<string>}
|
|
49
|
+
* @throws {Error} if the configured value is not an http(s) URL
|
|
50
|
+
*/
|
|
51
|
+
async function getWebBaseUrl() {
|
|
52
|
+
const { value, source } = await userConfig.getResolved('web.base_url');
|
|
53
|
+
const raw = String(value ?? '').trim();
|
|
54
|
+
|
|
55
|
+
let parsed = null;
|
|
56
|
+
try {
|
|
57
|
+
parsed = new URL(raw);
|
|
58
|
+
} catch {
|
|
59
|
+
parsed = null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!parsed || !/^https?:$/.test(parsed.protocol)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Invalid web.base_url (${source}): '${raw}'. `
|
|
65
|
+
+ 'Expected an http(s) URL, e.g. https://gent-nu2e.onrender.com. '
|
|
66
|
+
+ 'Set it with `gent config set web.base_url <url>`.'
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return stripTrailingSlash(parsed.href);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function stripTrailingSlash(url) {
|
|
74
|
+
return String(url || '').replace(/\/+$/, '');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Path (no host) of a repository page on the web app.
|
|
79
|
+
* Single source of truth for the repo route shape.
|
|
80
|
+
* @param {string|number} ownerId
|
|
81
|
+
* @param {string} repoName
|
|
82
|
+
* @returns {string}
|
|
83
|
+
*/
|
|
84
|
+
function repoPath(ownerId, repoName) {
|
|
85
|
+
return `/dashboard/repository/${encodeURIComponent(ownerId)}/${encodeURIComponent(repoName)}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Absolute URL of a repository page.
|
|
90
|
+
* @param {string} baseUrl - Web app base URL
|
|
91
|
+
* @param {string|number} ownerId
|
|
92
|
+
* @param {string} repoName
|
|
93
|
+
* @returns {string}
|
|
94
|
+
*/
|
|
95
|
+
function repoUrl(baseUrl, ownerId, repoName) {
|
|
96
|
+
return `${stripTrailingSlash(baseUrl)}${repoPath(ownerId, repoName)}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Build the best available link for the requested target.
|
|
101
|
+
*
|
|
102
|
+
* Because branch/commit pages don't exist, a branch or commit request resolves
|
|
103
|
+
* to the repo page and reports `unsupported` so the caller can warn.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} baseUrl - Web app base URL
|
|
106
|
+
* @param {{ owner_id: string|number, repo_name: string }} info
|
|
107
|
+
* @param {{ branch?: string, commit?: string }} [target]
|
|
108
|
+
* @returns {{ url: string, unsupported: null|'branch'|'commit' }}
|
|
109
|
+
*/
|
|
110
|
+
function buildRepoLink(baseUrl, info, target = {}) {
|
|
111
|
+
const url = repoUrl(baseUrl, info.owner_id, info.repo_name);
|
|
112
|
+
let unsupported = null;
|
|
113
|
+
if (target.commit) unsupported = 'commit';
|
|
114
|
+
else if (target.branch) unsupported = 'branch';
|
|
115
|
+
return { url, unsupported };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = {
|
|
119
|
+
BRANCH_COMMIT_UNSUPPORTED,
|
|
120
|
+
getWebBaseUrl,
|
|
121
|
+
repoPath,
|
|
122
|
+
repoUrl,
|
|
123
|
+
buildRepoLink,
|
|
124
|
+
stripTrailingSlash,
|
|
125
|
+
};
|