jackherd 1.0.2 → 1.0.3
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/CHANGELOG.md +4 -0
- package/herdr-plugin/herdr-plugin.toml +1 -1
- package/install.sh +1 -1
- package/package.json +1 -1
- package/src/update/command.ts +8 -5
- package/src/update/package-manager.ts +11 -0
- package/src/update/update.ts +13 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
What changed for people who use jackherd, newest first.
|
|
4
4
|
|
|
5
|
+
## 1.0.3
|
|
6
|
+
|
|
7
|
+
- **Update through the old command.** `agent-kit update`, run after moving from `@crossdelta/agent-kit`, now installs `jh` globally. Before, it found the bundled copy already current and installed nothing, so `jh` stayed off your path.
|
|
8
|
+
|
|
5
9
|
## 1.0.2
|
|
6
10
|
|
|
7
11
|
- **npm.** The package carries keywords, so a search on npm finds it.
|
package/install.sh
CHANGED
|
@@ -9,7 +9,7 @@ set -eu
|
|
|
9
9
|
|
|
10
10
|
# The default is the version this file ships with. The release bump changes it together with
|
|
11
11
|
# package.json; install.test.ts fails while the two differ. Overridable, but only by a plain release.
|
|
12
|
-
JACKHERD_VERSION="${JACKHERD_VERSION:-1.0.
|
|
12
|
+
JACKHERD_VERSION="${JACKHERD_VERSION:-1.0.3}"
|
|
13
13
|
|
|
14
14
|
JACKHERD_PACKAGE='jackherd'
|
|
15
15
|
# Test seam: the terminal the wizard asks its questions on.
|
package/package.json
CHANGED
package/src/update/command.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { defaultUpdateCheck, lockedVersion } from '../sync/if-changed'
|
|
|
13
13
|
import { locateKit } from '../sync/kit-source'
|
|
14
14
|
import { readInstalledVersion } from '../version/installed-version'
|
|
15
15
|
import { CLI_NAME } from '../version/release'
|
|
16
|
-
import { detectPackageManager, legacyPackageRoot } from './package-manager'
|
|
16
|
+
import { detectPackageManager, legacyPackageRoot, shellHostedGlobalRoot } from './package-manager'
|
|
17
17
|
import { runUpdate, UPDATE_EXIT, type UpdateAdapters } from './update'
|
|
18
18
|
|
|
19
19
|
const USAGE = `Usage: ${CLI_NAME} update`
|
|
@@ -36,15 +36,18 @@ const runInherited = async (argv: readonly string[], cwd: string): Promise<numbe
|
|
|
36
36
|
const adaptersFor = async (): Promise<UpdateAdapters> => {
|
|
37
37
|
const { version, packageRoot } = await locateKit()
|
|
38
38
|
const home = homedir()
|
|
39
|
+
const realRoot = realpathSync(packageRoot)
|
|
40
|
+
const targetRoot = shellHostedGlobalRoot(realRoot) ?? realRoot
|
|
39
41
|
return {
|
|
40
42
|
installedVersion: version,
|
|
41
|
-
manager: detectPackageManager(
|
|
43
|
+
manager: detectPackageManager(realRoot),
|
|
42
44
|
latestVersion: defaultUpdateCheck().latestVersion,
|
|
43
|
-
installedVersionOnDisk: () => readInstalledVersion(
|
|
44
|
-
kitCli: [process.execPath, join(
|
|
45
|
+
installedVersionOnDisk: () => readInstalledVersion(targetRoot),
|
|
46
|
+
kitCli: [process.execPath, join(targetRoot, 'src', 'cli.ts')],
|
|
45
47
|
run: runInherited,
|
|
46
48
|
hasGlobalKit: async () => (await lockedVersion(home)) !== null,
|
|
47
|
-
hasLegacyPackage: () => existsSync(legacyPackageRoot(
|
|
49
|
+
hasLegacyPackage: () => existsSync(legacyPackageRoot(targetRoot)),
|
|
50
|
+
jhOnPath: () => Bun.which(CLI_NAME) !== null,
|
|
48
51
|
home,
|
|
49
52
|
projectRoot: findProjectRoot(process.cwd(), home, existsSync),
|
|
50
53
|
log: (line) => console.log(line),
|
|
@@ -25,6 +25,17 @@ export const detectPackageManager = (packageRoot: string): PackageManager | null
|
|
|
25
25
|
return GLOBAL_LOCATIONS.find(([pattern]) => pattern.test(path))?.[1] ?? null
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
const SHELL_DEPENDENCY = `/${LEGACY_PACKAGE_NAME}/node_modules/${PACKAGE_NAME}`
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Where a global jackherd lies when this one sits nested inside the `@crossdelta/agent-kit` shell, as npm lays
|
|
32
|
+
* it out (beside the shell, in the same global `node_modules`); null for any other layout, bun's flat one included.
|
|
33
|
+
*/
|
|
34
|
+
export const shellHostedGlobalRoot = (packageRoot: string): string | null => {
|
|
35
|
+
const path = packageRoot.replaceAll('\\', '/')
|
|
36
|
+
return path.endsWith(SHELL_DEPENDENCY) ? `${path.slice(0, -SHELL_DEPENDENCY.length)}/${PACKAGE_NAME}` : null
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
/**
|
|
29
40
|
* The argv, never a shell line, that installs `version` globally without running install scripts: the kit
|
|
30
41
|
* has none and a dependency's would run before the new code is looked at. Throws unless `version` is a plain release.
|
package/src/update/update.ts
CHANGED
|
@@ -18,6 +18,8 @@ export type UpdateAdapters = {
|
|
|
18
18
|
hasGlobalKit: () => Promise<boolean>
|
|
19
19
|
/** True when the package before the rename is installed globally beside this one. */
|
|
20
20
|
hasLegacyPackage: () => boolean
|
|
21
|
+
/** Whether a `jh` command is on the path; false when only the `@crossdelta/agent-kit` shell carries this jackherd. Asked before and after the install. */
|
|
22
|
+
jhOnPath: () => boolean
|
|
21
23
|
home: string
|
|
22
24
|
/** The project the working directory belongs to, or null. */
|
|
23
25
|
projectRoot: string | null
|
|
@@ -57,10 +59,16 @@ const installAndVerify = async (
|
|
|
57
59
|
return UPDATE_EXIT.error
|
|
58
60
|
}
|
|
59
61
|
|
|
62
|
+
const doneLine = (adapters: UpdateAdapters, manager: PackageManager, latest: string, jhWasOnPath: boolean): string => {
|
|
63
|
+
if (jhWasOnPath) return `${CLI_NAME} updated ${adapters.installedVersion} → ${latest}.`
|
|
64
|
+
if (adapters.jhOnPath()) return `${CLI_NAME} ${latest} installed globally.`
|
|
65
|
+
return `${CLI_NAME} ${latest} installed, but no ${CLI_NAME} is on your path yet: add the global bin directory of ${manager} to it.`
|
|
66
|
+
}
|
|
67
|
+
|
|
60
68
|
/**
|
|
61
69
|
* The update itself: installs the newest release, then runs the syncs with the freshly installed code. Does
|
|
62
|
-
* nothing when no newer release exists
|
|
63
|
-
* installs is the one it checked, and only a plain release reaches the command line.
|
|
70
|
+
* nothing when no newer release exists and `jh` is on the path; without `jh` it installs even the running
|
|
71
|
+
* version. The version it installs is the one it checked, and only a plain release reaches the command line.
|
|
64
72
|
*/
|
|
65
73
|
const updateToLatest = async (adapters: UpdateAdapters, manager: PackageManager): Promise<number> => {
|
|
66
74
|
const { installedVersion, log } = adapters
|
|
@@ -73,7 +81,8 @@ const updateToLatest = async (adapters: UpdateAdapters, manager: PackageManager)
|
|
|
73
81
|
log(`${CLI_NAME} update: the npm registry answered no plain release version, nothing was changed.`)
|
|
74
82
|
return UPDATE_EXIT.error
|
|
75
83
|
}
|
|
76
|
-
|
|
84
|
+
const jhWasOnPath = adapters.jhOnPath()
|
|
85
|
+
if (jhWasOnPath && !isNewerVersion(latest, installedVersion)) {
|
|
77
86
|
log(`${CLI_NAME} ${installedVersion} is the latest release.`)
|
|
78
87
|
return UPDATE_EXIT.ok
|
|
79
88
|
}
|
|
@@ -82,7 +91,7 @@ const updateToLatest = async (adapters: UpdateAdapters, manager: PackageManager)
|
|
|
82
91
|
for (const { argv, cwd } of await syncSteps(adapters)) {
|
|
83
92
|
if ((await adapters.run(argv, cwd)) !== 0) return failed(log, 'the sync', argv.join(' '))
|
|
84
93
|
}
|
|
85
|
-
log(
|
|
94
|
+
log(doneLine(adapters, manager, latest, jhWasOnPath))
|
|
86
95
|
return UPDATE_EXIT.ok
|
|
87
96
|
}
|
|
88
97
|
|