charness 3.1.0 → 3.2.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/.env.example +8 -7
- package/DEVELOPMENT.md +12 -6
- package/MIGRATION_1_TO_2.md +1 -1
- package/MIGRATION_RENAME_TO_CHARNESS.md +133 -0
- package/README.md +75 -581
- package/SETUP.md +539 -0
- package/dist/adapters/claudeCliAdapter.d.ts +1 -1
- package/dist/adapters/claudeCliAdapter.js +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.d.ts.map +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.js +2 -1
- package/dist/adapters/claudeJsonStreamAdapter.js.map +1 -1
- package/dist/adapters/openCodeAdapter.js +1 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +7 -6
- package/dist/bot.js.map +1 -1
- package/dist/cli/bot.d.ts +4 -2
- package/dist/cli/bot.d.ts.map +1 -1
- package/dist/cli/bot.js +11 -3
- package/dist/cli/bot.js.map +1 -1
- package/dist/cli/botEntry.js +3 -1
- package/dist/cli/botEntry.js.map +1 -1
- package/dist/cli/claudeProfiles.d.ts +3 -3
- package/dist/cli/claudeProfiles.js +4 -4
- package/dist/cli/claudeProfiles.js.map +1 -1
- package/dist/cli/envLoader.d.ts +6 -5
- package/dist/cli/envLoader.d.ts.map +1 -1
- package/dist/cli/envLoader.js +8 -27
- package/dist/cli/envLoader.js.map +1 -1
- package/dist/cli/hot.d.ts +2 -2
- package/dist/cli/hot.d.ts.map +1 -1
- package/dist/cli/hot.js +26 -16
- package/dist/cli/hot.js.map +1 -1
- package/dist/cli.js +12 -12
- package/dist/cli.js.map +1 -1
- package/dist/connectors/jira/adf.d.ts +21 -0
- package/dist/connectors/jira/adf.d.ts.map +1 -1
- package/dist/connectors/jira/adf.js +39 -0
- package/dist/connectors/jira/adf.js.map +1 -1
- package/dist/connectors/jira/answerSink.d.ts +20 -3
- package/dist/connectors/jira/answerSink.d.ts.map +1 -1
- package/dist/connectors/jira/answerSink.js +126 -13
- package/dist/connectors/jira/answerSink.js.map +1 -1
- package/dist/connectors/jira/client.d.ts +4 -0
- package/dist/connectors/jira/client.d.ts.map +1 -1
- package/dist/connectors/jira/client.js +3 -0
- package/dist/connectors/jira/client.js.map +1 -1
- package/dist/connectors/jira/config.d.ts +10 -1
- package/dist/connectors/jira/config.d.ts.map +1 -1
- package/dist/connectors/jira/config.js +11 -2
- package/dist/connectors/jira/config.js.map +1 -1
- package/dist/connectors/jira/connector.d.ts +7 -1
- package/dist/connectors/jira/connector.d.ts.map +1 -1
- package/dist/connectors/jira/connector.js +23 -4
- package/dist/connectors/jira/connector.js.map +1 -1
- package/dist/connectors/jira/contextLedger.d.ts +6 -0
- package/dist/connectors/jira/contextLedger.d.ts.map +1 -1
- package/dist/connectors/jira/contextLedger.js +16 -0
- package/dist/connectors/jira/contextLedger.js.map +1 -1
- package/dist/connectors/jira/contextPreamble.d.ts.map +1 -1
- package/dist/connectors/jira/contextPreamble.js +6 -3
- package/dist/connectors/jira/contextPreamble.js.map +1 -1
- package/dist/connectors/jira/inbound.d.ts +60 -7
- package/dist/connectors/jira/inbound.d.ts.map +1 -1
- package/dist/connectors/jira/inbound.js +169 -16
- package/dist/connectors/jira/inbound.js.map +1 -1
- package/dist/connectors/jira/issueBlocks.d.ts +6 -1
- package/dist/connectors/jira/issueBlocks.d.ts.map +1 -1
- package/dist/connectors/jira/issueBlocks.js +5 -1
- package/dist/connectors/jira/issueBlocks.js.map +1 -1
- package/dist/connectors/jira/prompt.d.ts +2 -0
- package/dist/connectors/jira/prompt.d.ts.map +1 -1
- package/dist/connectors/jira/prompt.js +16 -0
- package/dist/connectors/jira/prompt.js.map +1 -1
- package/dist/connectors/jira/trigger.d.ts +12 -3
- package/dist/connectors/jira/trigger.d.ts.map +1 -1
- package/dist/connectors/jira/trigger.js +8 -1
- package/dist/connectors/jira/trigger.js.map +1 -1
- package/dist/connectors/jira/triggerLog.d.ts +10 -3
- package/dist/connectors/jira/triggerLog.d.ts.map +1 -1
- package/dist/connectors/jira/triggerLog.js +18 -2
- package/dist/connectors/jira/triggerLog.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installManager.d.ts +16 -2
- package/dist/installManager.d.ts.map +1 -1
- package/dist/installManager.js +42 -12
- package/dist/installManager.js.map +1 -1
- package/dist/instanceLock.d.ts.map +1 -1
- package/dist/instanceLock.js +10 -8
- package/dist/instanceLock.js.map +1 -1
- package/dist/legacyMigration.d.ts +69 -0
- package/dist/legacyMigration.d.ts.map +1 -0
- package/dist/legacyMigration.js +338 -0
- package/dist/legacyMigration.js.map +1 -0
- package/dist/legacyNames.d.ts +107 -0
- package/dist/legacyNames.d.ts.map +1 -0
- package/dist/legacyNames.js +230 -0
- package/dist/legacyNames.js.map +1 -0
- package/dist/platform/answerSink.d.ts +5 -0
- package/dist/platform/answerSink.d.ts.map +1 -1
- package/dist/platform/answerSink.js.map +1 -1
- package/dist/requests/answerRequest.d.ts +2 -0
- package/dist/requests/answerRequest.d.ts.map +1 -1
- package/dist/requests/answerRequest.js +3 -1
- package/dist/requests/answerRequest.js.map +1 -1
- package/dist/requests/answerStyle.d.ts +11 -0
- package/dist/requests/answerStyle.d.ts.map +1 -0
- package/dist/requests/answerStyle.js +14 -0
- package/dist/requests/answerStyle.js.map +1 -0
- package/dist/requests/answerTail.d.ts.map +1 -1
- package/dist/requests/answerTail.js +2 -0
- package/dist/requests/answerTail.js.map +1 -1
- package/dist/requests/requestHeader.d.ts.map +1 -1
- package/dist/requests/requestHeader.js +3 -0
- package/dist/requests/requestHeader.js.map +1 -1
- package/dist/requests/requestLedger.js +1 -1
- package/dist/requests/requestLedger.js.map +1 -1
- package/dist/requests/types.d.ts +3 -1
- package/dist/requests/types.d.ts.map +1 -1
- package/dist/scheduler/mcpSurface.d.ts +9 -1
- package/dist/scheduler/mcpSurface.d.ts.map +1 -1
- package/dist/scheduler/mcpSurface.js +45 -12
- package/dist/scheduler/mcpSurface.js.map +1 -1
- package/dist/state.d.ts +3 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +5 -2
- package/dist/state.js.map +1 -1
- package/dist/utils/claudeProfiles.d.ts +7 -0
- package/dist/utils/claudeProfiles.d.ts.map +1 -1
- package/dist/utils/claudeProfiles.js +19 -0
- package/dist/utils/claudeProfiles.js.map +1 -1
- package/dist/utils/openCodeCompactPlugin.d.ts +11 -3
- package/dist/utils/openCodeCompactPlugin.d.ts.map +1 -1
- package/dist/utils/openCodeCompactPlugin.js +37 -5
- package/dist/utils/openCodeCompactPlugin.js.map +1 -1
- package/examples/.env.example +7 -7
- package/examples/docker-compose.yml +15 -14
- package/package.json +3 -1
package/dist/instanceLock.js
CHANGED
|
@@ -45,6 +45,7 @@ const path = __importStar(require("path"));
|
|
|
45
45
|
const os = __importStar(require("os"));
|
|
46
46
|
const crypto = __importStar(require("crypto"));
|
|
47
47
|
const shutdown_1 = require("./shutdown");
|
|
48
|
+
const legacyNames_1 = require("./legacyNames");
|
|
48
49
|
/**
|
|
49
50
|
* @description Number of acquisition attempts before giving up.
|
|
50
51
|
*
|
|
@@ -83,12 +84,13 @@ function getLockHolderState(holder, own) {
|
|
|
83
84
|
/**
|
|
84
85
|
* @description Resolve the data directory the lockfile lives in.
|
|
85
86
|
*
|
|
86
|
-
* Mirrors `
|
|
87
|
-
* acquisition runs BEFORE the bot module is loaded, and `state.ts`
|
|
88
|
-
* `process.env.DATA_DIR` at module scope which we want to avoid coupling
|
|
87
|
+
* Mirrors `state.ts`'s `resolveDataDir` — kept independent (not imported)
|
|
88
|
+
* because lock acquisition runs BEFORE the bot module is loaded, and `state.ts`
|
|
89
|
+
* reads `process.env.DATA_DIR` at module scope which we want to avoid coupling
|
|
90
|
+
* to. Both take the home-dir default from `resolveDefaultDataDir`.
|
|
89
91
|
*/
|
|
90
92
|
function dataDir() {
|
|
91
|
-
return process.env.DATA_DIR ||
|
|
93
|
+
return process.env.DATA_DIR || (0, legacyNames_1.resolveDefaultDataDir)();
|
|
92
94
|
}
|
|
93
95
|
/** @description Lockfile path: `${DATA_DIR}/instance.lock`. */
|
|
94
96
|
function lockPath() {
|
|
@@ -141,7 +143,7 @@ function readLock(lp) {
|
|
|
141
143
|
*
|
|
142
144
|
* 12 hex chars from SHA-256 is enough collision resistance for "is this the
|
|
143
145
|
* same token the running instance is using" but reveals nothing useful to an
|
|
144
|
-
* attacker who reads
|
|
146
|
+
* attacker who reads `<DATA_DIR>/instance.lock`.
|
|
145
147
|
*/
|
|
146
148
|
function hashToken(token) {
|
|
147
149
|
if (!token)
|
|
@@ -299,7 +301,7 @@ async function acquireLock() {
|
|
|
299
301
|
if (r.ok)
|
|
300
302
|
return;
|
|
301
303
|
if (r.reason === 'live-holder') {
|
|
302
|
-
process.stderr.write(`
|
|
304
|
+
process.stderr.write(`charness is already running:\n` +
|
|
303
305
|
` pid: ${r.holder.pid}\n` +
|
|
304
306
|
` cwd: ${r.holder.cwd}\n` +
|
|
305
307
|
` started: ${r.holder.startedAt}\n` +
|
|
@@ -308,7 +310,7 @@ async function acquireLock() {
|
|
|
308
310
|
`Stop the running instance first, or set DATA_DIR to use a separate state dir.\n`);
|
|
309
311
|
}
|
|
310
312
|
else if (r.reason === 'foreign-host') {
|
|
311
|
-
process.stderr.write(`
|
|
313
|
+
process.stderr.write(`charness is locked by an instance on another host, which cannot be checked from here:\n` +
|
|
312
314
|
` host: ${r.holder.hostname}\n` +
|
|
313
315
|
` pid: ${r.holder.pid}\n` +
|
|
314
316
|
` started: ${r.holder.startedAt}\n` +
|
|
@@ -316,7 +318,7 @@ async function acquireLock() {
|
|
|
316
318
|
`Stop that instance; if it is already gone, remove the lock file and start again.\n`);
|
|
317
319
|
}
|
|
318
320
|
else {
|
|
319
|
-
process.stderr.write(`
|
|
321
|
+
process.stderr.write(`charness could not acquire ${r.lockPath} after retry. ` +
|
|
320
322
|
`Another instance is likely starting concurrently.\n`);
|
|
321
323
|
}
|
|
322
324
|
process.exit(1);
|
package/dist/instanceLock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instanceLock.js","sourceRoot":"","sources":["../src/instanceLock.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"instanceLock.js","sourceRoot":"","sources":["../src/instanceLock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description The automatic, idempotent move from the pre-rename names to the
|
|
3
|
+
* Charness ones, run at a COLD start of the bot: the global config dir
|
|
4
|
+
* (`~/.config/telegramcode`, older `~/.config/telegram-code` → `~/.config/charness`)
|
|
5
|
+
* and the default data dir (`~/.telegramCode` → `~/.charness`). Each moved dir
|
|
6
|
+
* leaves a relative SYMLINK at its old path, so a tmux / json-stream agent that
|
|
7
|
+
* still holds an old absolute path, an external script and an older mirror keep
|
|
8
|
+
* working. `legacyNames.ts` stays the read-fallback for whatever this does not
|
|
9
|
+
* (or could not) move.
|
|
10
|
+
*
|
|
11
|
+
* WHEN it runs — and the rules that keep it safe:
|
|
12
|
+
* - cold start only: the plain `charness` start and the hot SUPERVISOR's start.
|
|
13
|
+
* A hot WORKER reload never migrates (its supervisor, possibly the pre-rename
|
|
14
|
+
* code, still holds paths in the data dir — the caller passes nothing and
|
|
15
|
+
* this module is never reached from the worker).
|
|
16
|
+
* - under the instance lock, before the state is loaded (the caller acquires
|
|
17
|
+
* it; {@link migrateLegacyNamesUnderLock} takes it itself for the supervisor).
|
|
18
|
+
* - never for an isolated instance (`ENV_FILE`): it reads only its own file and
|
|
19
|
+
* its own dirs, and the shared config and default data dir belong to another
|
|
20
|
+
* bot. Never for an explicit `DATA_DIR`, whatever it names.
|
|
21
|
+
* - idempotent: a target that exists, or an old path that is already a symlink
|
|
22
|
+
* (ours, or the operator's own), skips the step; nothing is ever deleted; a
|
|
23
|
+
* failed step is logged and leaves BOTH sides usable (a failed symlink rolls
|
|
24
|
+
* the move back).
|
|
25
|
+
* - `TELEGRAMCODE_*` keys are renamed to `CHARNESS_*` only in the global config
|
|
26
|
+
* file this migration moved (a `.bak` copy first). `ENV_FILE` and `$PWD/.env`
|
|
27
|
+
* are never rewritten: the first is the operator's own, possibly read-only
|
|
28
|
+
* and mounted into a container; the second belongs to whatever project the
|
|
29
|
+
* bot was launched from.
|
|
30
|
+
*
|
|
31
|
+
* One log line per action taken. A step that is skipped because there is nothing
|
|
32
|
+
* to do is silent, so a second start prints nothing.
|
|
33
|
+
*/
|
|
34
|
+
import * as fs from 'fs';
|
|
35
|
+
type FsOps = Pick<typeof fs, 'lstatSync' | 'renameSync' | 'symlinkSync' | 'realpathSync' | 'readFileSync' | 'writeFileSync' | 'copyFileSync' | 'chmodSync' | 'existsSync' | 'unlinkSync'>;
|
|
36
|
+
export interface LegacyMigrationOptions {
|
|
37
|
+
homeDir?: string;
|
|
38
|
+
env?: NodeJS.ProcessEnv;
|
|
39
|
+
/** One line per action taken. */
|
|
40
|
+
log?: (line: string) => void;
|
|
41
|
+
/** One line per failed step. */
|
|
42
|
+
warn?: (line: string) => void;
|
|
43
|
+
/** The file operations — injected by tests to make a step fail. */
|
|
44
|
+
fsOps?: FsOps;
|
|
45
|
+
}
|
|
46
|
+
export interface LegacyMigrationResult {
|
|
47
|
+
/** The lines logged for actions taken, in order. */
|
|
48
|
+
actions: string[];
|
|
49
|
+
/** The lines logged for steps that failed, in order. */
|
|
50
|
+
failures: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @description Whether a start has anything to migrate — cheap, so the hot
|
|
54
|
+
* supervisor takes the instance lock only when it will use it.
|
|
55
|
+
*/
|
|
56
|
+
export declare function hasPendingLegacyMigration(options?: LegacyMigrationOptions): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* @description Run the migration. The CALLER holds the instance lock. Safe to
|
|
59
|
+
* call on every cold start: with nothing to do it does nothing and says nothing.
|
|
60
|
+
*/
|
|
61
|
+
export declare function migrateLegacyNames(options?: LegacyMigrationOptions): LegacyMigrationResult;
|
|
62
|
+
/**
|
|
63
|
+
* @description The hot SUPERVISOR's cold start: take the instance lock for the
|
|
64
|
+
* length of the migration. A lock held by a live instance (or any failure to
|
|
65
|
+
* take it) skips the migration and says why; the next start tries again.
|
|
66
|
+
*/
|
|
67
|
+
export declare function migrateLegacyNamesUnderLock(options?: LegacyMigrationOptions): LegacyMigrationResult;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=legacyMigration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacyMigration.d.ts","sourceRoot":"","sources":["../src/legacyMigration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAmBzB,KAAK,KAAK,GAAG,IAAI,CACf,OAAO,EAAE,EACP,WAAW,GACX,YAAY,GACZ,aAAa,GACb,cAAc,GACd,cAAc,GACd,eAAe,GACf,cAAc,GACd,WAAW,GACX,YAAY,GACZ,YAAY,CACf,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,iCAAiC;IACjC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,gCAAgC;IAChC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,mEAAmE;IACnE,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,oDAAoD;IACpD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAoHD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAEvF;AAwED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CAgD9F;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CAwBvG"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description The automatic, idempotent move from the pre-rename names to the
|
|
4
|
+
* Charness ones, run at a COLD start of the bot: the global config dir
|
|
5
|
+
* (`~/.config/telegramcode`, older `~/.config/telegram-code` → `~/.config/charness`)
|
|
6
|
+
* and the default data dir (`~/.telegramCode` → `~/.charness`). Each moved dir
|
|
7
|
+
* leaves a relative SYMLINK at its old path, so a tmux / json-stream agent that
|
|
8
|
+
* still holds an old absolute path, an external script and an older mirror keep
|
|
9
|
+
* working. `legacyNames.ts` stays the read-fallback for whatever this does not
|
|
10
|
+
* (or could not) move.
|
|
11
|
+
*
|
|
12
|
+
* WHEN it runs — and the rules that keep it safe:
|
|
13
|
+
* - cold start only: the plain `charness` start and the hot SUPERVISOR's start.
|
|
14
|
+
* A hot WORKER reload never migrates (its supervisor, possibly the pre-rename
|
|
15
|
+
* code, still holds paths in the data dir — the caller passes nothing and
|
|
16
|
+
* this module is never reached from the worker).
|
|
17
|
+
* - under the instance lock, before the state is loaded (the caller acquires
|
|
18
|
+
* it; {@link migrateLegacyNamesUnderLock} takes it itself for the supervisor).
|
|
19
|
+
* - never for an isolated instance (`ENV_FILE`): it reads only its own file and
|
|
20
|
+
* its own dirs, and the shared config and default data dir belong to another
|
|
21
|
+
* bot. Never for an explicit `DATA_DIR`, whatever it names.
|
|
22
|
+
* - idempotent: a target that exists, or an old path that is already a symlink
|
|
23
|
+
* (ours, or the operator's own), skips the step; nothing is ever deleted; a
|
|
24
|
+
* failed step is logged and leaves BOTH sides usable (a failed symlink rolls
|
|
25
|
+
* the move back).
|
|
26
|
+
* - `TELEGRAMCODE_*` keys are renamed to `CHARNESS_*` only in the global config
|
|
27
|
+
* file this migration moved (a `.bak` copy first). `ENV_FILE` and `$PWD/.env`
|
|
28
|
+
* are never rewritten: the first is the operator's own, possibly read-only
|
|
29
|
+
* and mounted into a container; the second belongs to whatever project the
|
|
30
|
+
* bot was launched from.
|
|
31
|
+
*
|
|
32
|
+
* One log line per action taken. A step that is skipped because there is nothing
|
|
33
|
+
* to do is silent, so a second start prints nothing.
|
|
34
|
+
*/
|
|
35
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
36
|
+
if (k2 === undefined) k2 = k;
|
|
37
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
38
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
39
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
40
|
+
}
|
|
41
|
+
Object.defineProperty(o, k2, desc);
|
|
42
|
+
}) : (function(o, m, k, k2) {
|
|
43
|
+
if (k2 === undefined) k2 = k;
|
|
44
|
+
o[k2] = m[k];
|
|
45
|
+
}));
|
|
46
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
47
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
48
|
+
}) : function(o, v) {
|
|
49
|
+
o["default"] = v;
|
|
50
|
+
});
|
|
51
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
52
|
+
var ownKeys = function(o) {
|
|
53
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
54
|
+
var ar = [];
|
|
55
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
56
|
+
return ar;
|
|
57
|
+
};
|
|
58
|
+
return ownKeys(o);
|
|
59
|
+
};
|
|
60
|
+
return function (mod) {
|
|
61
|
+
if (mod && mod.__esModule) return mod;
|
|
62
|
+
var result = {};
|
|
63
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
64
|
+
__setModuleDefault(result, mod);
|
|
65
|
+
return result;
|
|
66
|
+
};
|
|
67
|
+
})();
|
|
68
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
69
|
+
exports.hasPendingLegacyMigration = hasPendingLegacyMigration;
|
|
70
|
+
exports.migrateLegacyNames = migrateLegacyNames;
|
|
71
|
+
exports.migrateLegacyNamesUnderLock = migrateLegacyNamesUnderLock;
|
|
72
|
+
const fs = __importStar(require("fs"));
|
|
73
|
+
const os = __importStar(require("os"));
|
|
74
|
+
const path = __importStar(require("path"));
|
|
75
|
+
const legacyNames_1 = require("./legacyNames");
|
|
76
|
+
const instanceLock_1 = require("./instanceLock");
|
|
77
|
+
/** The pre-rename key prefix in a config file, and what it becomes. */
|
|
78
|
+
const legacyEnvKeyPrefix = 'TELEGRAMCODE_';
|
|
79
|
+
const currentEnvKeyPrefix = 'CHARNESS_';
|
|
80
|
+
const envFileName = '.env';
|
|
81
|
+
const envBackupSuffix = '.bak';
|
|
82
|
+
function resolveOptions(options) {
|
|
83
|
+
return {
|
|
84
|
+
homeDir: options.homeDir ?? os.homedir(),
|
|
85
|
+
env: options.env ?? process.env,
|
|
86
|
+
log: options.log ?? ((line) => process.stderr.write(`${line}\n`)),
|
|
87
|
+
warn: options.warn ?? ((line) => process.stderr.write(`${line}\n`)),
|
|
88
|
+
fsOps: options.fsOps ?? fs,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function getPathKind(fsOps, target) {
|
|
92
|
+
try {
|
|
93
|
+
const stat = fsOps.lstatSync(target);
|
|
94
|
+
if (stat.isSymbolicLink())
|
|
95
|
+
return 'symlink';
|
|
96
|
+
return stat.isDirectory() ? 'directory' : 'other';
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
return error.code === 'ENOENT' ? 'missing' : 'other';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function describePath(homeDir, target) {
|
|
103
|
+
return target.startsWith(`${homeDir}${path.sep}`) ? `~${target.slice(homeDir.length)}` : target;
|
|
104
|
+
}
|
|
105
|
+
function describeError(error) {
|
|
106
|
+
return error instanceof Error ? error.message : String(error);
|
|
107
|
+
}
|
|
108
|
+
/** The pre-rename keys a config file still carries that can be renamed (no `CHARNESS_` twin yet). */
|
|
109
|
+
function findRenamableEnvKeys(content) {
|
|
110
|
+
const definedKeys = new Set();
|
|
111
|
+
for (const match of content.matchAll(/^[ \t]*(?:export[ \t]+)?([A-Za-z_][A-Za-z0-9_]*)[ \t]*=/gm)) {
|
|
112
|
+
definedKeys.add(match[1]);
|
|
113
|
+
}
|
|
114
|
+
const renamable = [];
|
|
115
|
+
for (const key of definedKeys) {
|
|
116
|
+
if (!key.startsWith(legacyEnvKeyPrefix) || key.length === legacyEnvKeyPrefix.length)
|
|
117
|
+
continue;
|
|
118
|
+
if (!definedKeys.has(`${currentEnvKeyPrefix}${key.slice(legacyEnvKeyPrefix.length)}`))
|
|
119
|
+
renamable.push(key);
|
|
120
|
+
}
|
|
121
|
+
return renamable;
|
|
122
|
+
}
|
|
123
|
+
function readEnvFileIfPresent(fsOps, filePath) {
|
|
124
|
+
try {
|
|
125
|
+
return String(fsOps.readFileSync(filePath, 'utf8'));
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* @description What a migration would do right now, in order. Reads the file
|
|
133
|
+
* system only. An isolated instance (`ENV_FILE`) plans nothing.
|
|
134
|
+
*/
|
|
135
|
+
function planMigration(options) {
|
|
136
|
+
const { homeDir, env, fsOps } = options;
|
|
137
|
+
if (env.ENV_FILE)
|
|
138
|
+
return [];
|
|
139
|
+
const steps = [];
|
|
140
|
+
const configRoot = path.join(homeDir, '.config');
|
|
141
|
+
const canonicalConfigDir = path.join(configRoot, legacyNames_1.configDirName);
|
|
142
|
+
const canonicalConfigKind = getPathKind(fsOps, canonicalConfigDir);
|
|
143
|
+
const legacyConfigDirs = legacyNames_1.legacyConfigDirNames.map((name) => path.join(configRoot, name));
|
|
144
|
+
const movableConfigDir = canonicalConfigKind === 'missing'
|
|
145
|
+
? legacyConfigDirs.find((dir) => getPathKind(fsOps, dir) === 'directory')
|
|
146
|
+
: undefined;
|
|
147
|
+
if (movableConfigDir !== undefined) {
|
|
148
|
+
steps.push({ kind: 'move-dir', area: 'config', from: movableConfigDir, to: canonicalConfigDir });
|
|
149
|
+
steps.push({ kind: 'rename-env-keys', envFile: path.join(canonicalConfigDir, envFileName), legacyDir: movableConfigDir });
|
|
150
|
+
}
|
|
151
|
+
else if (canonicalConfigKind === 'directory') {
|
|
152
|
+
// A move of an earlier start whose key rename failed: the old path is our symlink to the canonical dir.
|
|
153
|
+
const envFile = path.join(canonicalConfigDir, envFileName);
|
|
154
|
+
const linkedLegacyDir = legacyConfigDirs.find((dir) => isSymlinkTo(fsOps, dir, canonicalConfigDir));
|
|
155
|
+
const content = linkedLegacyDir === undefined ? null : readEnvFileIfPresent(fsOps, envFile);
|
|
156
|
+
if (linkedLegacyDir !== undefined && content !== null && findRenamableEnvKeys(content).length > 0) {
|
|
157
|
+
steps.push({ kind: 'rename-env-keys', envFile, legacyDir: linkedLegacyDir });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// An explicit DATA_DIR is the operator's, whatever it names.
|
|
161
|
+
if (!env.DATA_DIR) {
|
|
162
|
+
const legacyDataDir = path.join(homeDir, legacyNames_1.legacyDefaultDataDirName);
|
|
163
|
+
const canonicalDataDir = path.join(homeDir, legacyNames_1.defaultDataDirName);
|
|
164
|
+
if (getPathKind(fsOps, legacyDataDir) === 'directory' && getPathKind(fsOps, canonicalDataDir) === 'missing') {
|
|
165
|
+
steps.push({ kind: 'move-dir', area: 'data', from: legacyDataDir, to: canonicalDataDir });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return steps;
|
|
169
|
+
}
|
|
170
|
+
function isSymlinkTo(fsOps, linkPath, targetDir) {
|
|
171
|
+
if (getPathKind(fsOps, linkPath) !== 'symlink')
|
|
172
|
+
return false;
|
|
173
|
+
try {
|
|
174
|
+
return fsOps.realpathSync(linkPath) === fsOps.realpathSync(targetDir);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* @description Whether a start has anything to migrate — cheap, so the hot
|
|
182
|
+
* supervisor takes the instance lock only when it will use it.
|
|
183
|
+
*/
|
|
184
|
+
function hasPendingLegacyMigration(options = {}) {
|
|
185
|
+
return planMigration(resolveOptions(options)).length > 0;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Rename the dir and leave a relative symlink at the old path. If the symlink
|
|
189
|
+
* cannot be made the move is undone, so the old path never ends up missing.
|
|
190
|
+
*/
|
|
191
|
+
function moveDirLeavingSymlink(fsOps, from, to, warn) {
|
|
192
|
+
fsOps.renameSync(from, to);
|
|
193
|
+
try {
|
|
194
|
+
fsOps.symlinkSync(path.basename(to), from);
|
|
195
|
+
}
|
|
196
|
+
catch (symlinkError) {
|
|
197
|
+
try {
|
|
198
|
+
fsOps.renameSync(to, from);
|
|
199
|
+
}
|
|
200
|
+
catch (rollbackError) {
|
|
201
|
+
warn(`[migrate] ${from} was moved to ${to} and the symlink back failed (${describeError(symlinkError)}), ` +
|
|
202
|
+
`and so did undoing the move (${describeError(rollbackError)}): link ${from} to ${to} by hand`);
|
|
203
|
+
}
|
|
204
|
+
throw symlinkError;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function findFreeBackupPath(fsOps, envFile) {
|
|
208
|
+
const firstChoice = `${envFile}${envBackupSuffix}`;
|
|
209
|
+
return fsOps.existsSync(firstChoice) ? `${firstChoice}.${Date.now()}` : firstChoice;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Rename `TELEGRAMCODE_*` keys to `CHARNESS_*` in one file, after a backup copy.
|
|
213
|
+
* The file's mode and a symlinked file's link are kept (the real file is
|
|
214
|
+
* rewritten in place by rename). Returns the keys renamed.
|
|
215
|
+
*/
|
|
216
|
+
function renameEnvFileKeys(fsOps, envFile) {
|
|
217
|
+
let realFile;
|
|
218
|
+
try {
|
|
219
|
+
realFile = fsOps.realpathSync(envFile);
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
// A config dir without a `.env` has no keys to rename.
|
|
223
|
+
if (error.code === 'ENOENT')
|
|
224
|
+
return null;
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
const content = String(fsOps.readFileSync(realFile, 'utf8'));
|
|
228
|
+
const keys = findRenamableEnvKeys(content);
|
|
229
|
+
if (keys.length === 0)
|
|
230
|
+
return null;
|
|
231
|
+
const renamedKeys = new Set(keys);
|
|
232
|
+
const rewritten = content.replace(/^([ \t]*(?:export[ \t]+)?)(TELEGRAMCODE_[A-Za-z0-9_]+)(?=[ \t]*=)/gm, (whole, prefix, key) => renamedKeys.has(key) ? `${prefix}${currentEnvKeyPrefix}${key.slice(legacyEnvKeyPrefix.length)}` : whole);
|
|
233
|
+
if (rewritten === content)
|
|
234
|
+
return null;
|
|
235
|
+
const mode = fsOps.lstatSync(realFile).mode & 0o777;
|
|
236
|
+
const backupPath = findFreeBackupPath(fsOps, realFile);
|
|
237
|
+
fsOps.copyFileSync(realFile, backupPath, fs.constants.COPYFILE_EXCL);
|
|
238
|
+
const tempPath = `${realFile}.tmp-${process.pid}`;
|
|
239
|
+
try {
|
|
240
|
+
fsOps.writeFileSync(tempPath, rewritten, { mode });
|
|
241
|
+
fsOps.chmodSync(tempPath, mode);
|
|
242
|
+
fsOps.renameSync(tempPath, realFile);
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
try {
|
|
246
|
+
fsOps.unlinkSync(tempPath);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
// never written
|
|
250
|
+
}
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
return { keys, backupPath };
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* @description Run the migration. The CALLER holds the instance lock. Safe to
|
|
257
|
+
* call on every cold start: with nothing to do it does nothing and says nothing.
|
|
258
|
+
*/
|
|
259
|
+
function migrateLegacyNames(options = {}) {
|
|
260
|
+
const resolved = resolveOptions(options);
|
|
261
|
+
const { homeDir, fsOps } = resolved;
|
|
262
|
+
const result = { actions: [], failures: [] };
|
|
263
|
+
const logAction = (line) => {
|
|
264
|
+
result.actions.push(line);
|
|
265
|
+
resolved.log(line);
|
|
266
|
+
};
|
|
267
|
+
const logFailure = (line) => {
|
|
268
|
+
result.failures.push(line);
|
|
269
|
+
resolved.warn(line);
|
|
270
|
+
};
|
|
271
|
+
const failedMoves = new Set();
|
|
272
|
+
for (const step of planMigration(resolved)) {
|
|
273
|
+
if (step.kind === 'move-dir') {
|
|
274
|
+
const fromLabel = describePath(homeDir, step.from);
|
|
275
|
+
const toLabel = describePath(homeDir, step.to);
|
|
276
|
+
try {
|
|
277
|
+
moveDirLeavingSymlink(fsOps, step.from, step.to, resolved.warn);
|
|
278
|
+
logAction(`[migrate] moved ${fromLabel} to ${toLabel}; ${fromLabel} is now a symlink to it`);
|
|
279
|
+
if (step.area === 'data')
|
|
280
|
+
(0, legacyNames_1.redecideDefaultDataDir)(homeDir);
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
failedMoves.add(step.from);
|
|
284
|
+
logFailure(`[migrate] could not move ${fromLabel} to ${toLabel} (${describeError(error)}): it stays where it is and ` +
|
|
285
|
+
`is still used; move it by hand with the bot stopped (see ${legacyNames_1.renameMigrationDoc})`);
|
|
286
|
+
}
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (failedMoves.has(step.legacyDir))
|
|
290
|
+
continue;
|
|
291
|
+
const envLabel = describePath(homeDir, step.envFile);
|
|
292
|
+
try {
|
|
293
|
+
const renamed = renameEnvFileKeys(fsOps, step.envFile);
|
|
294
|
+
if (renamed === null)
|
|
295
|
+
continue;
|
|
296
|
+
logAction(`[migrate] renamed ${renamed.keys.length} key(s) ${legacyEnvKeyPrefix}* to ${currentEnvKeyPrefix}* in ` +
|
|
297
|
+
`${envLabel} (${renamed.keys.join(', ')}); the old file is kept as ${describePath(homeDir, renamed.backupPath)}`);
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
logFailure(`[migrate] could not rename the ${legacyEnvKeyPrefix}* keys in ${envLabel} (${describeError(error)}): ` +
|
|
301
|
+
`rename them by hand (see ${legacyNames_1.renameMigrationDoc})`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* @description The hot SUPERVISOR's cold start: take the instance lock for the
|
|
308
|
+
* length of the migration. A lock held by a live instance (or any failure to
|
|
309
|
+
* take it) skips the migration and says why; the next start tries again.
|
|
310
|
+
*/
|
|
311
|
+
function migrateLegacyNamesUnderLock(options = {}) {
|
|
312
|
+
const resolved = resolveOptions(options);
|
|
313
|
+
const empty = { actions: [], failures: [] };
|
|
314
|
+
if (!hasPendingLegacyMigration(options))
|
|
315
|
+
return empty;
|
|
316
|
+
let lock;
|
|
317
|
+
try {
|
|
318
|
+
lock = (0, instanceLock_1.tryAcquireLock)();
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
const line = `[migrate] skipped: the instance lock could not be taken (${describeError(error)})`;
|
|
322
|
+
resolved.warn(line);
|
|
323
|
+
return { actions: [], failures: [line] };
|
|
324
|
+
}
|
|
325
|
+
if (!lock.ok) {
|
|
326
|
+
const line = `[migrate] skipped: another instance holds the lock on this data dir (${lock.reason}); ` +
|
|
327
|
+
`the old names keep working and the next cold start tries again`;
|
|
328
|
+
resolved.warn(line);
|
|
329
|
+
return { actions: [], failures: [line] };
|
|
330
|
+
}
|
|
331
|
+
try {
|
|
332
|
+
return migrateLegacyNames(options);
|
|
333
|
+
}
|
|
334
|
+
finally {
|
|
335
|
+
(0, instanceLock_1.releaseLock)();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=legacyMigration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacyMigration.js","sourceRoot":"","sources":["../src/legacyMigration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description The names the project had before it was renamed from TelegramCode
|
|
3
|
+
* to Charness, and the one place that knows how a running instance falls back to
|
|
4
|
+
* them.
|
|
5
|
+
*
|
|
6
|
+
* WHY a fallback exists: instances hot-reload `main`, so for a while old and new
|
|
7
|
+
* code meet — the hot SUPERVISOR keeps running the code it was started with (and
|
|
8
|
+
* keeps setting the old env var names for each new worker), other hosts' mirrors
|
|
9
|
+
* pull the rename without moving their data dir, and a running agent keeps the
|
|
10
|
+
* MCP header its launch config named. Every renamed name is therefore read as
|
|
11
|
+
* `new ?? old`, the old one only as a fallback, and each use of a fallback is
|
|
12
|
+
* announced ONCE per process, naming the migration doc.
|
|
13
|
+
*
|
|
14
|
+
* Nothing here moves a user's file: the fallback only decides which existing path
|
|
15
|
+
* is read. Moving them is `legacyMigration.ts`'s job, at a cold start.
|
|
16
|
+
*/
|
|
17
|
+
/** The document an operator or an agent finds the old → new table and the steps in. */
|
|
18
|
+
export declare const renameMigrationDoc = "MIGRATION_RENAME_TO_CHARNESS.md";
|
|
19
|
+
/** Default `DATA_DIR` under the home dir, and the one the pre-rename releases used. */
|
|
20
|
+
export declare const defaultDataDirName = ".charness";
|
|
21
|
+
export declare const legacyDefaultDataDirName = ".telegramCode";
|
|
22
|
+
/**
|
|
23
|
+
* Per-user config dir under `~/.config`, and the ones earlier releases used,
|
|
24
|
+
* newest first: `telegramcode` before the rename, `telegram-code` before that.
|
|
25
|
+
*/
|
|
26
|
+
export declare const configDirName = "charness";
|
|
27
|
+
export declare const legacyConfigDirNames: readonly string[];
|
|
28
|
+
/** A renamed environment variable: the current name and the one earlier releases used. */
|
|
29
|
+
export interface RenamedEnvName {
|
|
30
|
+
current: string;
|
|
31
|
+
legacy: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The supervisor → worker handshake of hot mode (`charness hot`). An operator
|
|
35
|
+
* never sets these: the supervisor does, so a legacy one reaching a worker means
|
|
36
|
+
* the supervisor still runs pre-rename code.
|
|
37
|
+
*/
|
|
38
|
+
export declare const hotReloadEnvName: RenamedEnvName;
|
|
39
|
+
export declare const openCodeProcessFileEnvName: RenamedEnvName;
|
|
40
|
+
/**
|
|
41
|
+
* @description The value of a renamed variable: the current name wins, the legacy
|
|
42
|
+
* one is the fallback. An empty value counts as unset, as everywhere the bot
|
|
43
|
+
* reads these.
|
|
44
|
+
*/
|
|
45
|
+
export declare function readRenamedEnv(env: NodeJS.ProcessEnv, name: RenamedEnvName): string | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* @description The default `DATA_DIR` (no explicit `DATA_DIR`): `~/.charness`,
|
|
48
|
+
* except that an existing `~/.telegramCode` is kept while `~/.charness` does not
|
|
49
|
+
* exist — an install made before the rename keeps its state where it is. A
|
|
50
|
+
* `~/.charness` that holds no `state.json` while `~/.telegramCode` does (made by
|
|
51
|
+
* hand, or as the parent of another instance's explicit `DATA_DIR`) does not
|
|
52
|
+
* take over either: the bot would start with none of its bindings. Never creates
|
|
53
|
+
* or moves anything.
|
|
54
|
+
*
|
|
55
|
+
* Decided ONCE per process and home dir: several modules resolve their paths at
|
|
56
|
+
* load and others at every call, and a `~/.charness` that appears while the
|
|
57
|
+
* process runs (the console tee creates it on a fresh install; an operator may
|
|
58
|
+
* `mkdir` it) must not make the two halves disagree until the next restart.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveDefaultDataDir(homeDir?: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* @description Decide the default `DATA_DIR` again, forgetting the earlier
|
|
63
|
+
* decision — for the one place that moves the dir (`legacyMigration.ts`), so the
|
|
64
|
+
* rest of the process sees the new path from then on.
|
|
65
|
+
*/
|
|
66
|
+
export declare function redecideDefaultDataDir(homeDir?: string): string;
|
|
67
|
+
/** @description `~/.config/<dirName>/.env` under `homeDir`. */
|
|
68
|
+
export declare function buildGlobalConfigEnvPath(dirName: string, homeDir?: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* @description The per-user global config file: `~/.config/charness/.env`, else
|
|
71
|
+
* the first existing of the earlier releases' dirs. When none exists the
|
|
72
|
+
* canonical path is returned — the location a fresh install should use. Nothing
|
|
73
|
+
* is moved.
|
|
74
|
+
*/
|
|
75
|
+
export declare function resolveGlobalConfigEnvPath(homeDir?: string): string;
|
|
76
|
+
/** @description The deprecation line every fallback prints: what to rename, to what, and where it is written down. */
|
|
77
|
+
export declare function formatDeprecation(legacyName: string, currentName: string): string;
|
|
78
|
+
type WriteLine = (text: string) => void;
|
|
79
|
+
/**
|
|
80
|
+
* @description Print one deprecation line, once per process per `key`. Returns
|
|
81
|
+
* whether it printed. The default sink is `process.stderr` (read at call time, so
|
|
82
|
+
* the console tee sees it).
|
|
83
|
+
*/
|
|
84
|
+
export declare function warnLegacyNameOnce(key: string, message: string, write?: WriteLine): boolean;
|
|
85
|
+
/** Forget what was announced and decided — for tests, which assert the once-only rules per case. */
|
|
86
|
+
export declare function resetLegacyNameState(): void;
|
|
87
|
+
/** One fallback in use at boot. */
|
|
88
|
+
export interface LegacyNameUse {
|
|
89
|
+
key: string;
|
|
90
|
+
message: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @description Every legacy name the environment and the home dir make the
|
|
94
|
+
* process fall back to right now: a legacy supervisor variable with no current
|
|
95
|
+
* one, the global config dir when it is a pre-rename one, and the default data
|
|
96
|
+
* dir when it is the pre-rename one. (The MCP header and the plugin file are
|
|
97
|
+
* announced where they are seen.)
|
|
98
|
+
*/
|
|
99
|
+
export declare function findLegacyNameUses(env?: NodeJS.ProcessEnv, homeDir?: string): LegacyNameUse[];
|
|
100
|
+
/**
|
|
101
|
+
* @description The boot-time announcement: print each fallback in use, once per
|
|
102
|
+
* process. Called by the plain start (after the console tee, so it reaches the
|
|
103
|
+
* bot log) and by the hot supervisor.
|
|
104
|
+
*/
|
|
105
|
+
export declare function warnLegacyNamesAtBoot(env?: NodeJS.ProcessEnv, homeDir?: string, write?: WriteLine): void;
|
|
106
|
+
export {};
|
|
107
|
+
//# sourceMappingURL=legacyNames.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacyNames.d.ts","sourceRoot":"","sources":["../src/legacyNames.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,oCAAoC,CAAC;AAEpE,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAsC,CAAC;AAEzF,0FAA0F;AAC1F,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAG9B,CAAC;AACF,eAAO,MAAM,0BAA0B,EAAE,cAGxC,CAAC;AAGF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAE/F;AAOD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,MAAqB,GAAG,MAAM,CAY5E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,MAAqB,GAAG,MAAM,CAG7E;AAED,+DAA+D;AAC/D,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAqB,GAAG,MAAM,CAEhG;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,MAAqB,GAAG,MAAM,CAQjF;AAED,sHAAsH;AACtH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAQxC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,SAAyB,GAAG,OAAO,CAK1G;AAED,oGAAoG;AACpG,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C;AAED,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAqB,GAC7B,aAAa,EAAE,CA+BjB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,MAAqB,EAC9B,KAAK,GAAE,SAAyB,GAC/B,IAAI,CAEN"}
|