@serviceme/devtools-core 0.3.3 → 0.4.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/device.d.mts +1 -1
- package/dist/device.d.ts +1 -1
- package/dist/device.js +12 -5
- package/dist/device.js.map +1 -1
- package/dist/device.mjs +12 -5
- package/dist/device.mjs.map +1 -1
- package/dist/{index-BmxS1A9G.d.ts → index-CR1hbAnO.d.ts} +19 -1
- package/dist/{index-GAigCT0j.d.mts → index-CXvNx2fp.d.mts} +19 -1
- package/dist/index.d.mts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +109 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +107 -36
- package/dist/index.mjs.map +1 -1
- package/dist/submit.d.mts +1 -1
- package/dist/submit.d.ts +1 -1
- package/dist/toolbox.d.mts +4 -0
- package/dist/toolbox.d.ts +4 -0
- package/dist/toolbox.js +34 -5
- package/dist/toolbox.js.map +1 -1
- package/dist/toolbox.mjs +34 -5
- package/dist/toolbox.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -59,6 +59,7 @@ __export(src_exports, {
|
|
|
59
59
|
EnvironmentInspector: () => EnvironmentInspector,
|
|
60
60
|
FsIdentityFileBackend: () => FsIdentityFileBackend,
|
|
61
61
|
FsToolboxFileBackend: () => FsToolboxFileBackend,
|
|
62
|
+
GIT_PROXY_PATH_SUFFIX: () => GIT_PROXY_PATH_SUFFIX,
|
|
62
63
|
GitClient: () => GitClient,
|
|
63
64
|
GitError: () => GitError,
|
|
64
65
|
GitHubAuthProvider: () => GitHubAuthProvider,
|
|
@@ -125,6 +126,7 @@ __export(src_exports, {
|
|
|
125
126
|
bootstrapPhase5Placeholders: () => bootstrapPhase5Placeholders,
|
|
126
127
|
buildDefaultReposFile: () => buildDefaultReposFile,
|
|
127
128
|
buildGitHubLocalEmail: () => buildGitHubLocalEmail,
|
|
129
|
+
buildGitProxyBase: () => buildGitProxyBase,
|
|
128
130
|
buildSignedHeaders: () => buildSignedHeaders,
|
|
129
131
|
copilotDoctor: () => copilotDoctor,
|
|
130
132
|
copilotPrompt: () => copilotPrompt,
|
|
@@ -2185,6 +2187,7 @@ var FILE_MODE = 384;
|
|
|
2185
2187
|
var LOCK_DIR_MODE = 448;
|
|
2186
2188
|
var DEFAULT_LOCK_TIMEOUT_MS = 5e3;
|
|
2187
2189
|
var DEFAULT_LOCK_RETRY_MS = 25;
|
|
2190
|
+
var LOCK_STALE_GRACE_MS = 200;
|
|
2188
2191
|
var TMP_SUFFIX = ".tmp";
|
|
2189
2192
|
var FsIdentityFileBackend = class {
|
|
2190
2193
|
async exists(filePath) {
|
|
@@ -2289,14 +2292,20 @@ var FileLock = class {
|
|
|
2289
2292
|
}
|
|
2290
2293
|
}
|
|
2291
2294
|
async isStaleLock() {
|
|
2295
|
+
let pidStr;
|
|
2292
2296
|
try {
|
|
2293
|
-
|
|
2294
|
-
const pid = Number.parseInt(pidStr.trim(), 10);
|
|
2295
|
-
if (!Number.isFinite(pid) || pid <= 0) return true;
|
|
2296
|
-
return !isProcessAlive(pid);
|
|
2297
|
+
pidStr = await fsp.readFile(this.pidFilePath, "utf8");
|
|
2297
2298
|
} catch {
|
|
2298
|
-
|
|
2299
|
+
try {
|
|
2300
|
+
const stat7 = await fsp.stat(this.dirPath);
|
|
2301
|
+
return Date.now() - stat7.mtimeMs > LOCK_STALE_GRACE_MS;
|
|
2302
|
+
} catch {
|
|
2303
|
+
return false;
|
|
2304
|
+
}
|
|
2299
2305
|
}
|
|
2306
|
+
const pid = Number.parseInt(pidStr.trim(), 10);
|
|
2307
|
+
if (!Number.isFinite(pid) || pid <= 0) return true;
|
|
2308
|
+
return !isProcessAlive(pid);
|
|
2300
2309
|
}
|
|
2301
2310
|
async release() {
|
|
2302
2311
|
if (!this.acquired) return;
|
|
@@ -2596,9 +2605,9 @@ var DraftsStore = class {
|
|
|
2596
2605
|
const dir = resolveDraftDir(kind, id);
|
|
2597
2606
|
const manifestFilename = kind === "skill" ? "SKILL.md" : "AGENT.md";
|
|
2598
2607
|
const manifestPath = path6.join(dir, manifestFilename);
|
|
2599
|
-
let
|
|
2608
|
+
let stat7;
|
|
2600
2609
|
try {
|
|
2601
|
-
|
|
2610
|
+
stat7 = await fs4.stat(manifestPath);
|
|
2602
2611
|
} catch {
|
|
2603
2612
|
return null;
|
|
2604
2613
|
}
|
|
@@ -2617,7 +2626,7 @@ var DraftsStore = class {
|
|
|
2617
2626
|
dir,
|
|
2618
2627
|
name,
|
|
2619
2628
|
description,
|
|
2620
|
-
modifiedAt:
|
|
2629
|
+
modifiedAt: stat7.mtime.toISOString()
|
|
2621
2630
|
};
|
|
2622
2631
|
}
|
|
2623
2632
|
/** Single draft detail (summary + all files). Throws when missing. */
|
|
@@ -2733,10 +2742,33 @@ var POSIX_LOGIN_SHELL_FALLBACK_TOOLS = /* @__PURE__ */ new Set([
|
|
|
2733
2742
|
]);
|
|
2734
2743
|
var ERROR_CODE_NOT_FOUND = 127;
|
|
2735
2744
|
var ERROR_CODE_TIMEOUT = "ETIMEDOUT";
|
|
2745
|
+
var NVM_FALLBACK_DIRS = [
|
|
2746
|
+
"/opt/homebrew/opt/nvm",
|
|
2747
|
+
"/usr/local/opt/nvm",
|
|
2748
|
+
"$HOME/.nvm"
|
|
2749
|
+
];
|
|
2750
|
+
function resolveUserLoginShell(platform3, envShell) {
|
|
2751
|
+
const shell = envShell?.trim();
|
|
2752
|
+
if (shell && shell.length > 0) {
|
|
2753
|
+
return shell;
|
|
2754
|
+
}
|
|
2755
|
+
return platform3 === "darwin" ? "/bin/zsh" : "/bin/bash";
|
|
2756
|
+
}
|
|
2757
|
+
function buildNvmSourcingSnippet() {
|
|
2758
|
+
const fallbackList = NVM_FALLBACK_DIRS.map((dir) => `"${dir}"`).join(" ");
|
|
2759
|
+
return `for d in $NVM_DIR ${fallbackList}; do [ -n "$d" ] && [ -s "$d/nvm.sh" ] && export NVM_DIR="$d" && . "$d/nvm.sh" && break; done`;
|
|
2760
|
+
}
|
|
2761
|
+
function posixLoginShellArgs(platform3, envShell, command) {
|
|
2762
|
+
return {
|
|
2763
|
+
command: resolveUserLoginShell(platform3, envShell),
|
|
2764
|
+
args: ["-lc", `${buildNvmSourcingSnippet()}; ${command}`]
|
|
2765
|
+
};
|
|
2766
|
+
}
|
|
2736
2767
|
var EnvironmentInspector = class {
|
|
2737
2768
|
constructor(options = {}) {
|
|
2738
2769
|
this.runCommandFn = options.runCommand ?? runCommand;
|
|
2739
2770
|
this.platform = options.platform ?? process.platform;
|
|
2771
|
+
this.shell = options.shell ?? process.env.SHELL;
|
|
2740
2772
|
}
|
|
2741
2773
|
async checkEnvironment() {
|
|
2742
2774
|
const results = await Promise.all(
|
|
@@ -2783,11 +2815,9 @@ var EnvironmentInspector = class {
|
|
|
2783
2815
|
}
|
|
2784
2816
|
async getToolPathFromLoginShell(toolName) {
|
|
2785
2817
|
try {
|
|
2786
|
-
const
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
'export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; command -v ' + toolName
|
|
2790
|
-
],
|
|
2818
|
+
const spawnArgs = posixLoginShellArgs(this.platform, this.shell, `command -v ${toolName}`);
|
|
2819
|
+
const result = await this.runCommandFn(spawnArgs.command, {
|
|
2820
|
+
args: spawnArgs.args,
|
|
2791
2821
|
timeoutMs: this.getToolTimeout(toolName)
|
|
2792
2822
|
});
|
|
2793
2823
|
return result.stdout.split(/\r?\n/).map((line) => line.trim()).find((line) => line.length > 0);
|
|
@@ -2826,11 +2856,9 @@ var EnvironmentInspector = class {
|
|
|
2826
2856
|
if (!this.shouldUsePosixLoginShellFallback(toolName)) {
|
|
2827
2857
|
throw error;
|
|
2828
2858
|
}
|
|
2829
|
-
const
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
`export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; ${toolName} --version`
|
|
2833
|
-
],
|
|
2859
|
+
const fallbackArgs = posixLoginShellArgs(this.platform, this.shell, `${toolName} --version`);
|
|
2860
|
+
const fallbackResult = await this.runCommandFn(fallbackArgs.command, {
|
|
2861
|
+
args: fallbackArgs.args,
|
|
2834
2862
|
timeoutMs: this.getToolTimeout(toolName)
|
|
2835
2863
|
});
|
|
2836
2864
|
const fallbackOutput = (fallbackResult.stdout || fallbackResult.stderr).trim();
|
|
@@ -2863,11 +2891,9 @@ var EnvironmentInspector = class {
|
|
|
2863
2891
|
}
|
|
2864
2892
|
}
|
|
2865
2893
|
try {
|
|
2866
|
-
const
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
'export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; nvm --version'
|
|
2870
|
-
],
|
|
2894
|
+
const nvmArgs = posixLoginShellArgs(this.platform, this.shell, "nvm --version");
|
|
2895
|
+
const result = await this.runCommandFn(nvmArgs.command, {
|
|
2896
|
+
args: nvmArgs.args,
|
|
2871
2897
|
timeoutMs: this.getToolTimeout("nvm")
|
|
2872
2898
|
});
|
|
2873
2899
|
return {
|
|
@@ -3054,7 +3080,9 @@ var GitClient = class {
|
|
|
3054
3080
|
}
|
|
3055
3081
|
const targetUrl = useProxy ? remoteUrl : originalUrl ?? remoteUrl;
|
|
3056
3082
|
const proxyUrl = this.rewriteRemoteUrl(repoId, targetUrl, useProxy);
|
|
3057
|
-
await this.runOrThrow(["remote", "set-url", "origin", proxyUrl], {
|
|
3083
|
+
await this.runOrThrow(["remote", "set-url", "origin", proxyUrl], {
|
|
3084
|
+
cwd: localPath
|
|
3085
|
+
});
|
|
3058
3086
|
const before = await this.safeRevParse(localPath);
|
|
3059
3087
|
await this.runOrThrow(["fetch", "origin"], { cwd: localPath });
|
|
3060
3088
|
const after = await this.safeRevParse(localPath);
|
|
@@ -3090,7 +3118,9 @@ var GitClient = class {
|
|
|
3090
3118
|
throw new Error(`no 'origin' remote configured at ${localPath}`);
|
|
3091
3119
|
}
|
|
3092
3120
|
const proxyUrl = this.rewriteRemoteUrl(repoId, remoteUrl, useProxy);
|
|
3093
|
-
await this.runOrThrow(["remote", "set-url", "origin", proxyUrl], {
|
|
3121
|
+
await this.runOrThrow(["remote", "set-url", "origin", proxyUrl], {
|
|
3122
|
+
cwd: localPath
|
|
3123
|
+
});
|
|
3094
3124
|
const result = await this.spawner.spawn(
|
|
3095
3125
|
["push", "origin", `refs/heads/${branch}:refs/heads/${branch}`],
|
|
3096
3126
|
{ cwd: localPath }
|
|
@@ -3144,7 +3174,9 @@ var GitClient = class {
|
|
|
3144
3174
|
return { commitSha: sha };
|
|
3145
3175
|
}
|
|
3146
3176
|
async runOrThrow(args, opts) {
|
|
3147
|
-
const result = await this.spawner.spawn(args, {
|
|
3177
|
+
const result = await this.spawner.spawn(args, {
|
|
3178
|
+
cwd: opts.cwd ?? process.cwd()
|
|
3179
|
+
});
|
|
3148
3180
|
if (result.code !== 0) {
|
|
3149
3181
|
throw new GitError(args, result);
|
|
3150
3182
|
}
|
|
@@ -3159,7 +3191,9 @@ var GitClient = class {
|
|
|
3159
3191
|
return url.length > 0 ? url : void 0;
|
|
3160
3192
|
}
|
|
3161
3193
|
async safeRevParse(localPath) {
|
|
3162
|
-
const result = await this.spawner.spawn(["rev-parse", "HEAD"], {
|
|
3194
|
+
const result = await this.spawner.spawn(["rev-parse", "HEAD"], {
|
|
3195
|
+
cwd: localPath
|
|
3196
|
+
});
|
|
3163
3197
|
if (result.code !== 0) return "";
|
|
3164
3198
|
return result.stdout.trim();
|
|
3165
3199
|
}
|
|
@@ -3206,7 +3240,11 @@ var StubGitSpawner = class {
|
|
|
3206
3240
|
this.calls.push({ args, cwd: opts.cwd });
|
|
3207
3241
|
const next = this.script.shift();
|
|
3208
3242
|
if (!next) {
|
|
3209
|
-
return {
|
|
3243
|
+
return {
|
|
3244
|
+
stdout: "",
|
|
3245
|
+
stderr: `stub: no scripted response for ${args.join(" ")}`,
|
|
3246
|
+
code: 1
|
|
3247
|
+
};
|
|
3210
3248
|
}
|
|
3211
3249
|
return next;
|
|
3212
3250
|
}
|
|
@@ -3218,6 +3256,10 @@ function toFileUrl(absolutePath) {
|
|
|
3218
3256
|
}
|
|
3219
3257
|
return `file://${normalized}`;
|
|
3220
3258
|
}
|
|
3259
|
+
var GIT_PROXY_PATH_SUFFIX = "/git-proxy";
|
|
3260
|
+
function buildGitProxyBase(serverBaseUrl) {
|
|
3261
|
+
return `${serverBaseUrl.replace(/\/+$/, "")}${GIT_PROXY_PATH_SUFFIX}`;
|
|
3262
|
+
}
|
|
3221
3263
|
|
|
3222
3264
|
// src/image/imageTools.ts
|
|
3223
3265
|
var fs5 = __toESM(require("fs/promises"));
|
|
@@ -4852,13 +4894,13 @@ var PidManager = class {
|
|
|
4852
4894
|
fs13.writeFileSync(this.pidPath, String(pid), "utf-8");
|
|
4853
4895
|
}
|
|
4854
4896
|
readPid() {
|
|
4855
|
-
let
|
|
4897
|
+
let stat7;
|
|
4856
4898
|
try {
|
|
4857
|
-
|
|
4899
|
+
stat7 = fs13.statSync(this.pidPath);
|
|
4858
4900
|
} catch {
|
|
4859
4901
|
return null;
|
|
4860
4902
|
}
|
|
4861
|
-
if (!
|
|
4903
|
+
if (!stat7.isFile()) return null;
|
|
4862
4904
|
const raw = fs13.readFileSync(this.pidPath, "utf-8").trim();
|
|
4863
4905
|
const pid = Number.parseInt(raw, 10);
|
|
4864
4906
|
return Number.isNaN(pid) ? null : pid;
|
|
@@ -6989,6 +7031,7 @@ var FILE_MODE2 = 384;
|
|
|
6989
7031
|
var LOCK_DIR_MODE2 = 448;
|
|
6990
7032
|
var DEFAULT_LOCK_TIMEOUT_MS2 = 5e3;
|
|
6991
7033
|
var DEFAULT_LOCK_RETRY_MS2 = 25;
|
|
7034
|
+
var LOCK_STALE_GRACE_MS2 = 200;
|
|
6992
7035
|
var TMP_SUFFIX2 = ".tmp";
|
|
6993
7036
|
var WORKSPACE_TOOLBOX_RELATIVE_PATH = path25.join(".github", ".serviceme-toolbox.json");
|
|
6994
7037
|
var LEGACY_WORKSPACE_TOOLBOX_FILENAME = ".ms-devtools-toolbox.json";
|
|
@@ -7007,6 +7050,9 @@ async function migrateLegacyWorkspaceToolboxFile(filePath) {
|
|
|
7007
7050
|
}
|
|
7008
7051
|
}
|
|
7009
7052
|
var FsToolboxFileBackend = class {
|
|
7053
|
+
constructor() {
|
|
7054
|
+
this.maxBackupCount = 5;
|
|
7055
|
+
}
|
|
7010
7056
|
async exists(filePath) {
|
|
7011
7057
|
try {
|
|
7012
7058
|
await fsp2.access(filePath);
|
|
@@ -7035,9 +7081,28 @@ var FsToolboxFileBackend = class {
|
|
|
7035
7081
|
try {
|
|
7036
7082
|
const backupPath = `${filePath}.corrupted.${Date.now()}.bak`;
|
|
7037
7083
|
await fsp2.copyFile(filePath, backupPath);
|
|
7084
|
+
await this.purgeExcessBackups(filePath);
|
|
7038
7085
|
} catch {
|
|
7039
7086
|
}
|
|
7040
7087
|
}
|
|
7088
|
+
async purgeExcessBackups(filePath) {
|
|
7089
|
+
const dir = path25.dirname(filePath);
|
|
7090
|
+
const base = path25.basename(filePath);
|
|
7091
|
+
let entries;
|
|
7092
|
+
try {
|
|
7093
|
+
entries = await fsp2.readdir(dir);
|
|
7094
|
+
} catch {
|
|
7095
|
+
return;
|
|
7096
|
+
}
|
|
7097
|
+
const backups = entries.filter((n) => n.startsWith(base) && n.endsWith(".bak")).map((n) => ({ name: n, filePath: path25.join(dir, n) })).sort((a, b) => {
|
|
7098
|
+
return a.name.localeCompare(b.name);
|
|
7099
|
+
});
|
|
7100
|
+
const excess = backups.length - this.maxBackupCount;
|
|
7101
|
+
if (excess <= 0) return;
|
|
7102
|
+
await Promise.all(
|
|
7103
|
+
backups.slice(0, excess).map((b) => fsp2.rm(b.filePath).catch(() => void 0))
|
|
7104
|
+
);
|
|
7105
|
+
}
|
|
7041
7106
|
async write(filePath, payload) {
|
|
7042
7107
|
await fsp2.mkdir(path25.dirname(filePath), { recursive: true });
|
|
7043
7108
|
const tmpPath = `${filePath}${TMP_SUFFIX2}`;
|
|
@@ -7110,14 +7175,20 @@ var ToolboxFileLock = class {
|
|
|
7110
7175
|
}
|
|
7111
7176
|
}
|
|
7112
7177
|
async isStaleLock() {
|
|
7178
|
+
let pidStr;
|
|
7113
7179
|
try {
|
|
7114
|
-
|
|
7115
|
-
const pid = Number.parseInt(pidStr.trim(), 10);
|
|
7116
|
-
if (!Number.isFinite(pid) || pid <= 0) return true;
|
|
7117
|
-
return !isProcessAlive2(pid);
|
|
7180
|
+
pidStr = await fsp2.readFile(this.pidFilePath, "utf8");
|
|
7118
7181
|
} catch {
|
|
7119
|
-
|
|
7182
|
+
try {
|
|
7183
|
+
const stat7 = await fsp2.stat(this.dirPath);
|
|
7184
|
+
return Date.now() - stat7.mtimeMs > LOCK_STALE_GRACE_MS2;
|
|
7185
|
+
} catch {
|
|
7186
|
+
return false;
|
|
7187
|
+
}
|
|
7120
7188
|
}
|
|
7189
|
+
const pid = Number.parseInt(pidStr.trim(), 10);
|
|
7190
|
+
if (!Number.isFinite(pid) || pid <= 0) return true;
|
|
7191
|
+
return !isProcessAlive2(pid);
|
|
7121
7192
|
}
|
|
7122
7193
|
async release() {
|
|
7123
7194
|
if (!this.acquired) return;
|
|
@@ -7398,6 +7469,7 @@ var ToolboxCore = class {
|
|
|
7398
7469
|
EnvironmentInspector,
|
|
7399
7470
|
FsIdentityFileBackend,
|
|
7400
7471
|
FsToolboxFileBackend,
|
|
7472
|
+
GIT_PROXY_PATH_SUFFIX,
|
|
7401
7473
|
GitClient,
|
|
7402
7474
|
GitError,
|
|
7403
7475
|
GitHubAuthProvider,
|
|
@@ -7464,6 +7536,7 @@ var ToolboxCore = class {
|
|
|
7464
7536
|
bootstrapPhase5Placeholders,
|
|
7465
7537
|
buildDefaultReposFile,
|
|
7466
7538
|
buildGitHubLocalEmail,
|
|
7539
|
+
buildGitProxyBase,
|
|
7467
7540
|
buildSignedHeaders,
|
|
7468
7541
|
copilotDoctor,
|
|
7469
7542
|
copilotPrompt,
|