harness-wingman 0.8.0 → 0.8.1
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/apps/cli/dist/main.js +1131 -727
- package/apps/panel/dist/assets/index-BXQunvUx.css +1 -0
- package/apps/panel/dist/assets/index-F4lz9B32.js +231 -0
- package/apps/panel/dist/index.html +2 -2
- package/package.json +2 -2
- package/apps/panel/dist/assets/index-BquIYTp8.js +0 -231
- package/apps/panel/dist/assets/index-WYPdL-aq.css +0 -1
package/apps/cli/dist/main.js
CHANGED
|
@@ -7757,11 +7757,11 @@ function isPatchState(value) {
|
|
|
7757
7757
|
const patch = value;
|
|
7758
7758
|
return typeof patch.patchFile === "string" && typeof patch.original === "object" && patch.original !== null && typeof patch.original.existed === "boolean" && (patch.original.bytesBase64 === void 0 || typeof patch.original.bytesBase64 === "string");
|
|
7759
7759
|
}
|
|
7760
|
-
async function readState(
|
|
7761
|
-
const buffer = await readIfExists(
|
|
7760
|
+
async function readState(paths3) {
|
|
7761
|
+
const buffer = await readIfExists(paths3.stateFile);
|
|
7762
7762
|
if (buffer === void 0)
|
|
7763
7763
|
return void 0;
|
|
7764
|
-
const state = JSON.parse(decodeUtf8Strict(buffer,
|
|
7764
|
+
const state = JSON.parse(decodeUtf8Strict(buffer, paths3.stateFile));
|
|
7765
7765
|
if (typeof state !== "object" || state === null || state.version !== 1 && state.version !== 2) {
|
|
7766
7766
|
throw new Error("\u672A\u77E5\u7684\u63A5\u7EBF\u72B6\u6001\u7248\u672C,\u4E0D\u731C");
|
|
7767
7767
|
}
|
|
@@ -7770,18 +7770,18 @@ async function readState(paths) {
|
|
|
7770
7770
|
}
|
|
7771
7771
|
return state;
|
|
7772
7772
|
}
|
|
7773
|
-
async function writeState(
|
|
7774
|
-
await mkdir(dirname(
|
|
7775
|
-
await writeFile(
|
|
7773
|
+
async function writeState(paths3, state) {
|
|
7774
|
+
await mkdir(dirname(paths3.stateFile), { recursive: true });
|
|
7775
|
+
await writeFile(paths3.stateFile, `${JSON.stringify(state, void 0, 2)}
|
|
7776
7776
|
`, "utf8");
|
|
7777
7777
|
}
|
|
7778
|
-
function backupDirectory(
|
|
7779
|
-
return join(
|
|
7778
|
+
function backupDirectory(paths3) {
|
|
7779
|
+
return join(paths3.backupsRoot, (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-"));
|
|
7780
7780
|
}
|
|
7781
|
-
async function backupPatchFile(
|
|
7782
|
-
const fromProfiles = relative(
|
|
7781
|
+
async function backupPatchFile(paths3, backupDir, file, bytes) {
|
|
7782
|
+
const fromProfiles = relative(paths3.profilesDir, file);
|
|
7783
7783
|
let safeRelative;
|
|
7784
|
-
if (file ===
|
|
7784
|
+
if (file === paths3.patchFile) {
|
|
7785
7785
|
safeRelative = join("home", "cordis.patch.yml");
|
|
7786
7786
|
} else if (!fromProfiles.startsWith("..") && !isAbsolute(fromProfiles)) {
|
|
7787
7787
|
safeRelative = join("profiles", fromProfiles);
|
|
@@ -7793,15 +7793,15 @@ async function backupPatchFile(paths, backupDir, file, bytes) {
|
|
|
7793
7793
|
await mkdir(dirname(target), { recursive: true });
|
|
7794
7794
|
await writeFile(target, bytes);
|
|
7795
7795
|
}
|
|
7796
|
-
async function writeOwnedFiles(
|
|
7797
|
-
await mkdir(dirname(
|
|
7798
|
-
await writeFile(
|
|
7799
|
-
await writeFile(
|
|
7796
|
+
async function writeOwnedFiles(paths3, url) {
|
|
7797
|
+
await mkdir(dirname(paths3.hooksConfigFile), { recursive: true });
|
|
7798
|
+
await writeFile(paths3.forwarderFile, FORWARDER_SOURCE, "utf8");
|
|
7799
|
+
await writeFile(paths3.hooksConfigFile, buildHooksConfig(paths3.forwarderFile, url), "utf8");
|
|
7800
7800
|
}
|
|
7801
|
-
async function listProfiles(
|
|
7801
|
+
async function listProfiles(paths3, environment) {
|
|
7802
7802
|
let entries;
|
|
7803
7803
|
try {
|
|
7804
|
-
entries = await readdir(
|
|
7804
|
+
entries = await readdir(paths3.profilesDir, { withFileTypes: true });
|
|
7805
7805
|
} catch (error) {
|
|
7806
7806
|
if (error.code === "ENOENT")
|
|
7807
7807
|
entries = [];
|
|
@@ -7813,12 +7813,12 @@ async function listProfiles(paths, environment) {
|
|
|
7813
7813
|
if (entry.name === "node_modules")
|
|
7814
7814
|
continue;
|
|
7815
7815
|
try {
|
|
7816
|
-
if (!(await stat(join(
|
|
7816
|
+
if (!(await stat(join(paths3.profilesDir, entry.name))).isDirectory())
|
|
7817
7817
|
continue;
|
|
7818
7818
|
} catch {
|
|
7819
7819
|
continue;
|
|
7820
7820
|
}
|
|
7821
|
-
const manifest = join(
|
|
7821
|
+
const manifest = join(paths3.profilesDir, entry.name, "package.json");
|
|
7822
7822
|
if (await readIfExists(manifest) !== void 0)
|
|
7823
7823
|
names.push(entry.name);
|
|
7824
7824
|
}
|
|
@@ -7830,12 +7830,12 @@ async function listProfiles(paths, environment) {
|
|
|
7830
7830
|
const selectedNames = selected === void 0 || selected === "" ? names : [selected];
|
|
7831
7831
|
const inspected = [];
|
|
7832
7832
|
for (const name of selectedNames) {
|
|
7833
|
-
const dir = join(
|
|
7833
|
+
const dir = join(paths3.profilesDir, name);
|
|
7834
7834
|
const missingPackages = [];
|
|
7835
7835
|
for (const packageName of REQUIRED_PACKAGES) {
|
|
7836
7836
|
const parts = packageName.split("/");
|
|
7837
7837
|
const localManifest = join(dir, "node_modules", ...parts, "package.json");
|
|
7838
|
-
const parentManifest = join(
|
|
7838
|
+
const parentManifest = join(paths3.profilesDir, "node_modules", ...parts, "package.json");
|
|
7839
7839
|
if (await readIfExists(localManifest) === void 0 && await readIfExists(parentManifest) === void 0) {
|
|
7840
7840
|
missingPackages.push(packageName);
|
|
7841
7841
|
}
|
|
@@ -7852,7 +7852,7 @@ async function listProfiles(paths, environment) {
|
|
|
7852
7852
|
function installCommand(profile) {
|
|
7853
7853
|
return `dsh plugin --profile ${profile} add ${DSH_HOOKS_PACKAGE}@${DSH_PINNED_VERSION} ${DSH_HOOK_PROTOCOL_PACKAGE}@${DSH_PINNED_VERSION}`;
|
|
7854
7854
|
}
|
|
7855
|
-
async function profileIsWired(profile,
|
|
7855
|
+
async function profileIsWired(profile, paths3) {
|
|
7856
7856
|
if (profile.missingPackages.length > 0)
|
|
7857
7857
|
return false;
|
|
7858
7858
|
const buffer = await readIfExists(profile.patchFile);
|
|
@@ -7869,18 +7869,18 @@ async function profileIsWired(profile, paths) {
|
|
|
7869
7869
|
const entries = tryParsePatchEntries(text, profile.patchFile);
|
|
7870
7870
|
if (entries === void 0 || !hasWingmanRow(entries))
|
|
7871
7871
|
return false;
|
|
7872
|
-
return await readIfExists(
|
|
7872
|
+
return await readIfExists(paths3.hooksConfigFile) !== void 0;
|
|
7873
7873
|
}
|
|
7874
7874
|
async function dshHookInstallReport(options, environment = process.env) {
|
|
7875
|
-
const
|
|
7876
|
-
const profiles = await listProfiles(
|
|
7875
|
+
const paths3 = resolveDshHookPaths(options);
|
|
7876
|
+
const profiles = await listProfiles(paths3, environment);
|
|
7877
7877
|
const reports = [];
|
|
7878
7878
|
for (const profile of profiles) {
|
|
7879
7879
|
const missingPackages = [...profile.missingPackages];
|
|
7880
7880
|
const blockPresent = hasLiveHooksBlock(await readIfExists(profile.patchFile));
|
|
7881
7881
|
const report = {
|
|
7882
7882
|
profile: profile.name,
|
|
7883
|
-
wired: await profileIsWired(profile,
|
|
7883
|
+
wired: await profileIsWired(profile, paths3),
|
|
7884
7884
|
blockPresent,
|
|
7885
7885
|
missingPackages
|
|
7886
7886
|
};
|
|
@@ -7890,16 +7890,16 @@ async function dshHookInstallReport(options, environment = process.env) {
|
|
|
7890
7890
|
}
|
|
7891
7891
|
return { profiles: reports };
|
|
7892
7892
|
}
|
|
7893
|
-
function prepareInstalledProfile(profile,
|
|
7893
|
+
function prepareInstalledProfile(profile, paths3, before, previous) {
|
|
7894
7894
|
const currentText = before === void 0 ? void 0 : decodeUtf8Strict(before, profile.patchFile);
|
|
7895
7895
|
const surgicalText = currentText === void 0 ? void 0 : stripLiveHooksBlocks(currentText, profile.patchFile);
|
|
7896
7896
|
const entriesBefore = surgicalText === void 0 ? [] : parsePatchEntries(surgicalText, profile.patchFile);
|
|
7897
7897
|
if (hasWingmanRow(entriesBefore)) {
|
|
7898
7898
|
throw new Error(`\u62D2\u5199:${profile.patchFile} \u5DF2\u6709\u672A\u5E26 wingman \u6807\u8BB0\u7684 ${DSH_HOOK_ROW_ID} \u6761\u76EE(\u7591\u624B\u5DE5\u6284\u5165),\u8BF7\u5148\u624B\u5DE5\u79FB\u9664`);
|
|
7899
7899
|
}
|
|
7900
|
-
const composed = composeInstalledText(surgicalText, entriesBefore.length, buildPatchBlock(
|
|
7900
|
+
const composed = composeInstalledText(surgicalText, entriesBefore.length, buildPatchBlock(paths3.hooksConfigFile));
|
|
7901
7901
|
const composedEntries = parsePatchEntries(composed, profile.patchFile);
|
|
7902
|
-
const expected = [...entriesBefore, expectedEntry(
|
|
7902
|
+
const expected = [...entriesBefore, expectedEntry(paths3.hooksConfigFile)];
|
|
7903
7903
|
if (JSON.stringify(composedEntries) !== JSON.stringify(expected)) {
|
|
7904
7904
|
throw new Error(`\u62D2\u5199:${profile.patchFile} \u8FFD\u52A0\u540E\u5F62\u72B6\u6821\u9A8C\u5931\u8D25(\u539F\u6587\u4EF6\u5F62\u6001\u65E0\u6CD5\u5B89\u5168\u8FFD\u52A0),\u4E0D\u731C`);
|
|
7905
7905
|
}
|
|
@@ -7951,13 +7951,13 @@ function restoredFromSnapshot(after, state) {
|
|
|
7951
7951
|
return false;
|
|
7952
7952
|
return after.equals(Buffer2.from(state.original.bytesBase64, "base64"));
|
|
7953
7953
|
}
|
|
7954
|
-
async function applyMutations(
|
|
7954
|
+
async function applyMutations(paths3, mutations) {
|
|
7955
7955
|
if (mutations.length === 0)
|
|
7956
7956
|
return;
|
|
7957
|
-
const backupDir = backupDirectory(
|
|
7957
|
+
const backupDir = backupDirectory(paths3);
|
|
7958
7958
|
for (const mutation of mutations) {
|
|
7959
7959
|
if (mutation.before !== void 0) {
|
|
7960
|
-
await backupPatchFile(
|
|
7960
|
+
await backupPatchFile(paths3, backupDir, mutation.file, mutation.before);
|
|
7961
7961
|
}
|
|
7962
7962
|
}
|
|
7963
7963
|
for (const mutation of mutations) {
|
|
@@ -7970,22 +7970,22 @@ async function applyMutations(paths, mutations) {
|
|
|
7970
7970
|
}
|
|
7971
7971
|
}
|
|
7972
7972
|
async function retireLegacyDshHomeHooks(options) {
|
|
7973
|
-
const
|
|
7973
|
+
const paths3 = resolveDshHookPaths(options);
|
|
7974
7974
|
try {
|
|
7975
|
-
const before = await readIfExists(
|
|
7975
|
+
const before = await readIfExists(paths3.patchFile);
|
|
7976
7976
|
if (!hasLiveHooksBlock(before))
|
|
7977
7977
|
return { removed: false, restored: "none" };
|
|
7978
|
-
const state = await readState(
|
|
7978
|
+
const state = await readState(paths3);
|
|
7979
7979
|
const candidate = state?.version === 1 ? { patchFile: state.patchFile, original: state.original } : state?.legacyHome;
|
|
7980
|
-
const legacyState = candidate?.patchFile ===
|
|
7981
|
-
const mutation = prepareRemoval(
|
|
7980
|
+
const legacyState = candidate?.patchFile === paths3.patchFile ? candidate : void 0;
|
|
7981
|
+
const mutation = prepareRemoval(paths3.patchFile, before, legacyState);
|
|
7982
7982
|
if (mutation === void 0)
|
|
7983
7983
|
return { removed: false, restored: "none" };
|
|
7984
|
-
await applyMutations(
|
|
7984
|
+
await applyMutations(paths3, [mutation]);
|
|
7985
7985
|
return {
|
|
7986
7986
|
removed: true,
|
|
7987
7987
|
restored: restoredFromSnapshot(mutation.after, legacyState) ? "byte-identical" : "surgical",
|
|
7988
|
-
path:
|
|
7988
|
+
path: paths3.patchFile
|
|
7989
7989
|
};
|
|
7990
7990
|
} catch {
|
|
7991
7991
|
return {
|
|
@@ -7997,9 +7997,9 @@ async function installDshHooks(port, options, environment = process.env) {
|
|
|
7997
7997
|
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
7998
7998
|
throw new Error(`\u975E\u6CD5\u7AEF\u53E3:${String(port)}`);
|
|
7999
7999
|
}
|
|
8000
|
-
const
|
|
8001
|
-
const profiles = await listProfiles(
|
|
8002
|
-
const previousState = await readState(
|
|
8000
|
+
const paths3 = resolveDshHookPaths(options);
|
|
8001
|
+
const profiles = await listProfiles(paths3, environment);
|
|
8002
|
+
const previousState = await readState(paths3);
|
|
8003
8003
|
const previousProfiles = previousState?.version === 2 ? previousState.profiles : {};
|
|
8004
8004
|
const nextProfiles = { ...previousProfiles };
|
|
8005
8005
|
const mutations = [];
|
|
@@ -8007,7 +8007,7 @@ async function installDshHooks(port, options, environment = process.env) {
|
|
|
8007
8007
|
for (const profile of profiles) {
|
|
8008
8008
|
const before = await readIfExists(profile.patchFile);
|
|
8009
8009
|
if (profile.missingPackages.length === 0) {
|
|
8010
|
-
const prepared = prepareInstalledProfile(profile,
|
|
8010
|
+
const prepared = prepareInstalledProfile(profile, paths3, before, previousProfiles[profile.name]);
|
|
8011
8011
|
nextProfiles[profile.name] = prepared.state;
|
|
8012
8012
|
if (prepared.mutation !== void 0)
|
|
8013
8013
|
mutations.push(prepared.mutation);
|
|
@@ -8021,19 +8021,19 @@ async function installDshHooks(port, options, environment = process.env) {
|
|
|
8021
8021
|
}
|
|
8022
8022
|
}
|
|
8023
8023
|
let legacyHome = previousState?.version === 2 ? previousState.legacyHome : previousState?.version === 1 ? { patchFile: previousState.patchFile, original: previousState.original } : void 0;
|
|
8024
|
-
const legacyBefore = await readIfExists(
|
|
8024
|
+
const legacyBefore = await readIfExists(paths3.patchFile);
|
|
8025
8025
|
let migratedThisRun = false;
|
|
8026
8026
|
if (hasLiveHooksBlock(legacyBefore)) {
|
|
8027
|
-
const legacyText = decodeUtf8Strict(legacyBefore,
|
|
8028
|
-
parsePatchEntries(legacyText,
|
|
8029
|
-
const surgical = stripLiveHooksBlocks(legacyText,
|
|
8030
|
-
const surgicalEntries = parsePatchEntries(surgical,
|
|
8027
|
+
const legacyText = decodeUtf8Strict(legacyBefore, paths3.patchFile);
|
|
8028
|
+
parsePatchEntries(legacyText, paths3.patchFile);
|
|
8029
|
+
const surgical = stripLiveHooksBlocks(legacyText, paths3.patchFile);
|
|
8030
|
+
const surgicalEntries = parsePatchEntries(surgical, paths3.patchFile);
|
|
8031
8031
|
legacyHome ??= {
|
|
8032
|
-
patchFile:
|
|
8032
|
+
patchFile: paths3.patchFile,
|
|
8033
8033
|
original: { existed: true }
|
|
8034
8034
|
};
|
|
8035
|
-
const after = resolveRestoredBytes(surgical, surgicalEntries, legacyHome,
|
|
8036
|
-
mutations.push({ file:
|
|
8035
|
+
const after = resolveRestoredBytes(surgical, surgicalEntries, legacyHome, paths3.patchFile);
|
|
8036
|
+
mutations.push({ file: paths3.patchFile, before: legacyBefore, after });
|
|
8037
8037
|
migratedThisRun = true;
|
|
8038
8038
|
}
|
|
8039
8039
|
const nextState = {
|
|
@@ -8046,38 +8046,38 @@ async function installDshHooks(port, options, environment = process.env) {
|
|
|
8046
8046
|
const hasState = hasManagedProfiles || legacyHome !== void 0;
|
|
8047
8047
|
const url = `http://127.0.0.1:${port}/hook?harness=dsh`;
|
|
8048
8048
|
if (hasManagedProfiles) {
|
|
8049
|
-
await writeOwnedFiles(
|
|
8049
|
+
await writeOwnedFiles(paths3, url);
|
|
8050
8050
|
if (hasState)
|
|
8051
|
-
await writeState(
|
|
8051
|
+
await writeState(paths3, nextState);
|
|
8052
8052
|
else
|
|
8053
|
-
await rm(
|
|
8054
|
-
await applyMutations(
|
|
8053
|
+
await rm(paths3.stateFile, { force: true });
|
|
8054
|
+
await applyMutations(paths3, mutations);
|
|
8055
8055
|
} else {
|
|
8056
|
-
await applyMutations(
|
|
8057
|
-
await rm(
|
|
8058
|
-
await rm(
|
|
8056
|
+
await applyMutations(paths3, mutations);
|
|
8057
|
+
await rm(paths3.hooksConfigFile, { force: true });
|
|
8058
|
+
await rm(paths3.forwarderFile, { force: true });
|
|
8059
8059
|
if (hasState)
|
|
8060
|
-
await writeState(
|
|
8060
|
+
await writeState(paths3, nextState);
|
|
8061
8061
|
else
|
|
8062
|
-
await rm(
|
|
8062
|
+
await rm(paths3.stateFile, { force: true });
|
|
8063
8063
|
}
|
|
8064
8064
|
return { migratedThisRun, removedProfiles };
|
|
8065
8065
|
}
|
|
8066
8066
|
async function uninstallDshHooks(options, environment = process.env) {
|
|
8067
|
-
const
|
|
8068
|
-
const state = await readState(
|
|
8067
|
+
const paths3 = resolveDshHookPaths(options);
|
|
8068
|
+
const state = await readState(paths3);
|
|
8069
8069
|
const stateProfiles = state?.version === 2 ? state.profiles : {};
|
|
8070
8070
|
const selected = environment.WINGMAN_DSH_PROFILE;
|
|
8071
8071
|
const inspectionEnvironment = { ...environment };
|
|
8072
8072
|
delete inspectionEnvironment.WINGMAN_DSH_PROFILE;
|
|
8073
|
-
const inspected = await listProfiles(
|
|
8073
|
+
const inspected = await listProfiles(paths3, inspectionEnvironment);
|
|
8074
8074
|
if (selected !== void 0 && selected !== "" && !inspected.some((profile) => profile.name === selected) && stateProfiles[selected] === void 0) {
|
|
8075
8075
|
throw new Error(`dsh profile \u4E0D\u5B58\u5728\u6216\u7F3A package.json:${selected}`);
|
|
8076
8076
|
}
|
|
8077
8077
|
const targetNames = selected === void 0 || selected === "" ? [.../* @__PURE__ */ new Set([...inspected.map((profile) => profile.name), ...Object.keys(stateProfiles)])] : [selected];
|
|
8078
8078
|
const remainingProfiles = { ...stateProfiles };
|
|
8079
8079
|
for (const profile of inspected) {
|
|
8080
|
-
if (!targetNames.includes(profile.name) && await profileIsWired(profile,
|
|
8080
|
+
if (!targetNames.includes(profile.name) && await profileIsWired(profile, paths3)) {
|
|
8081
8081
|
remainingProfiles[profile.name] ??= {
|
|
8082
8082
|
patchFile: profile.patchFile,
|
|
8083
8083
|
original: { existed: true }
|
|
@@ -8088,10 +8088,10 @@ async function uninstallDshHooks(options, environment = process.env) {
|
|
|
8088
8088
|
const results = [];
|
|
8089
8089
|
for (const name of targetNames) {
|
|
8090
8090
|
const profileState = stateProfiles[name];
|
|
8091
|
-
const file = profileState?.patchFile ?? join(
|
|
8091
|
+
const file = profileState?.patchFile ?? join(paths3.profilesDir, name, "cordis.patch.yml");
|
|
8092
8092
|
const before = await readIfExists(file);
|
|
8093
8093
|
const inspectedProfile = inspected.find((profile) => profile.name === name);
|
|
8094
|
-
const wired = inspectedProfile === void 0 ? false : await profileIsWired(inspectedProfile,
|
|
8094
|
+
const wired = inspectedProfile === void 0 ? false : await profileIsWired(inspectedProfile, paths3);
|
|
8095
8095
|
const removal = prepareRemoval(file, before, profileState);
|
|
8096
8096
|
if (removal !== void 0) {
|
|
8097
8097
|
mutations.push(removal);
|
|
@@ -8105,31 +8105,31 @@ async function uninstallDshHooks(options, environment = process.env) {
|
|
|
8105
8105
|
delete remainingProfiles[name];
|
|
8106
8106
|
}
|
|
8107
8107
|
const legacyState = state?.version === 1 ? { patchFile: state.patchFile, original: state.original } : state?.legacyHome;
|
|
8108
|
-
const legacyFile = legacyState?.patchFile ??
|
|
8108
|
+
const legacyFile = legacyState?.patchFile ?? paths3.patchFile;
|
|
8109
8109
|
const legacyRemoval = prepareRemoval(legacyFile, await readIfExists(legacyFile), legacyState);
|
|
8110
8110
|
if (legacyRemoval !== void 0)
|
|
8111
8111
|
mutations.push(legacyRemoval);
|
|
8112
|
-
await applyMutations(
|
|
8112
|
+
await applyMutations(paths3, mutations);
|
|
8113
8113
|
if (Object.keys(remainingProfiles).length > 0) {
|
|
8114
|
-
await writeState(
|
|
8114
|
+
await writeState(paths3, {
|
|
8115
8115
|
version: 2,
|
|
8116
8116
|
port: state?.port ?? 7333,
|
|
8117
8117
|
profiles: remainingProfiles
|
|
8118
8118
|
});
|
|
8119
8119
|
} else {
|
|
8120
|
-
await rm(
|
|
8121
|
-
await rm(
|
|
8122
|
-
await rm(
|
|
8120
|
+
await rm(paths3.hooksConfigFile, { force: true });
|
|
8121
|
+
await rm(paths3.forwarderFile, { force: true });
|
|
8122
|
+
await rm(paths3.stateFile, { force: true });
|
|
8123
8123
|
}
|
|
8124
8124
|
return { profiles: results };
|
|
8125
8125
|
}
|
|
8126
8126
|
async function detectDshLiveWiring(options, environment = process.env) {
|
|
8127
|
-
const
|
|
8127
|
+
const paths3 = resolveDshHookPaths(options);
|
|
8128
8128
|
const inspectionEnvironment = { ...environment };
|
|
8129
8129
|
delete inspectionEnvironment.WINGMAN_DSH_PROFILE;
|
|
8130
|
-
const profiles = await listProfiles(
|
|
8130
|
+
const profiles = await listProfiles(paths3, inspectionEnvironment);
|
|
8131
8131
|
for (const profile of profiles) {
|
|
8132
|
-
if (await profileIsWired(profile,
|
|
8132
|
+
if (await profileIsWired(profile, paths3))
|
|
8133
8133
|
return true;
|
|
8134
8134
|
}
|
|
8135
8135
|
return false;
|
|
@@ -8193,17 +8193,19 @@ var init_feedback_url = __esm({
|
|
|
8193
8193
|
|
|
8194
8194
|
// packages/core/dist/plan-protocol.js
|
|
8195
8195
|
import { createHash as createHash2 } from "node:crypto";
|
|
8196
|
-
function planProtocolBlockStart(version = PLAN_PROTOCOL_VERSION) {
|
|
8197
|
-
return `<!-- >>> wingman plan protocol v${version} >>> -->`;
|
|
8196
|
+
function planProtocolBlockStart(version = PLAN_PROTOCOL_VERSION, scope = "project") {
|
|
8197
|
+
return `<!-- >>> wingman plan protocol ${scope === "user" ? "user " : ""}v${version} >>> -->`;
|
|
8198
8198
|
}
|
|
8199
|
-
function buildPlanProtocolBlock(version = PLAN_PROTOCOL_VERSION, text) {
|
|
8200
|
-
|
|
8199
|
+
function buildPlanProtocolBlock(version = PLAN_PROTOCOL_VERSION, text, scope = "project") {
|
|
8200
|
+
const known = scope === "user" ? KNOWN_USER_PROTOCOL_TEXT : KNOWN_PROTOCOL_TEXT;
|
|
8201
|
+
let body = normalizeMarkdownLineEndings(text ?? known.get(version) ?? "");
|
|
8201
8202
|
if (body === "")
|
|
8202
8203
|
throw new Error(`\u672A\u77E5 Plan Protocol \u7248\u672C v${version}\uFF0C\u4E14\u672A\u63D0\u4F9B\u6B63\u6587`);
|
|
8203
8204
|
if (!body.endsWith("\n"))
|
|
8204
8205
|
body += "\n";
|
|
8205
|
-
|
|
8206
|
-
|
|
8206
|
+
const end = scope === "user" ? PLAN_PROTOCOL_USER_BLOCK_END : PLAN_PROTOCOL_BLOCK_END;
|
|
8207
|
+
return `${planProtocolBlockStart(version, scope)}
|
|
8208
|
+
${body}${end}
|
|
8207
8209
|
`;
|
|
8208
8210
|
}
|
|
8209
8211
|
function decodeUtf8Strict2(bytes, sourcePath = "<memory>") {
|
|
@@ -8224,9 +8226,17 @@ function preferredMarkdownLineEnding(text) {
|
|
|
8224
8226
|
const hasBareLf = text.replaceAll("\r\n", "").includes("\n");
|
|
8225
8227
|
return hasCrlf && !hasBareLf ? "\r\n" : "\n";
|
|
8226
8228
|
}
|
|
8227
|
-
function splitPlanProtocolBlock(text, sourcePath = "<memory>") {
|
|
8228
|
-
const
|
|
8229
|
-
const
|
|
8229
|
+
function splitPlanProtocolBlock(text, sourcePath = "<memory>", scope = "project") {
|
|
8230
|
+
const startPattern = scope === "user" ? USER_BLOCK_START : BLOCK_START;
|
|
8231
|
+
const endMarker = scope === "user" ? PLAN_PROTOCOL_USER_BLOCK_END : PLAN_PROTOCOL_BLOCK_END;
|
|
8232
|
+
const starts = [...text.matchAll(startPattern)];
|
|
8233
|
+
const ends = allIndexesOf(text, endMarker);
|
|
8234
|
+
if (scope === "user") {
|
|
8235
|
+
const unrecognized = text.replace(startPattern, "").replaceAll(endMarker, "");
|
|
8236
|
+
if (/<!--\s*(?:>>>|<<<)\s*wingman plan protocol user\b/u.test(unrecognized)) {
|
|
8237
|
+
throw new Error(`wingman plan protocol user \u672A\u77E5\u6807\u8BB0\u683C\u5F0F(${sourcePath})`);
|
|
8238
|
+
}
|
|
8239
|
+
}
|
|
8230
8240
|
if (starts.length === 0 && ends.length === 0) {
|
|
8231
8241
|
return { before: text, after: "", remainder: text };
|
|
8232
8242
|
}
|
|
@@ -8238,7 +8248,7 @@ function splitPlanProtocolBlock(text, sourcePath = "<memory>") {
|
|
|
8238
8248
|
if (start === void 0 || endMark === void 0 || endMark < start.index) {
|
|
8239
8249
|
throw new Error(`wingman plan protocol \u6807\u8BB0\u5757\u6B8B\u7F3A(${sourcePath})`);
|
|
8240
8250
|
}
|
|
8241
|
-
let end = endMark +
|
|
8251
|
+
let end = endMark + endMarker.length;
|
|
8242
8252
|
if (text.startsWith("\r\n", end))
|
|
8243
8253
|
end += 2;
|
|
8244
8254
|
else if (text[end] === "\n")
|
|
@@ -8253,15 +8263,17 @@ function splitPlanProtocolBlock(text, sourcePath = "<memory>") {
|
|
|
8253
8263
|
version: Number(start[1])
|
|
8254
8264
|
};
|
|
8255
8265
|
}
|
|
8256
|
-
function inspectPlanProtocolBlock(block) {
|
|
8266
|
+
function inspectPlanProtocolBlock(block, scope = "project") {
|
|
8257
8267
|
const normalized = normalizeMarkdownLineEndings(block);
|
|
8258
|
-
const split = splitPlanProtocolBlock(normalized);
|
|
8268
|
+
const split = splitPlanProtocolBlock(normalized, "<memory>", scope);
|
|
8259
8269
|
const version = split.version;
|
|
8260
|
-
const
|
|
8261
|
-
const
|
|
8270
|
+
const currentVersion = scope === "user" ? PLAN_PROTOCOL_USER_VERSION : PLAN_PROTOCOL_VERSION;
|
|
8271
|
+
const knownTexts = scope === "user" ? KNOWN_USER_PROTOCOL_TEXT : KNOWN_PROTOCOL_TEXT;
|
|
8272
|
+
const knownText = version === void 0 ? void 0 : knownTexts.get(version);
|
|
8273
|
+
const knownBlock = version === void 0 || knownText === void 0 ? void 0 : buildPlanProtocolBlock(version, knownText, scope);
|
|
8262
8274
|
const known = split.before === "" && split.after === "" && normalized === knownBlock;
|
|
8263
8275
|
return {
|
|
8264
|
-
kind: known && version ===
|
|
8276
|
+
kind: known && version === currentVersion ? "current" : known ? "legacy" : "modified",
|
|
8265
8277
|
...version !== void 0 ? { version } : {},
|
|
8266
8278
|
sha256: sha256Hex(normalized)
|
|
8267
8279
|
};
|
|
@@ -8287,11 +8299,27 @@ function allIndexesOf(text, needle) {
|
|
|
8287
8299
|
}
|
|
8288
8300
|
return indexes;
|
|
8289
8301
|
}
|
|
8290
|
-
|
|
8302
|
+
function mergePlanProtocolBlock(text, block, sourcePath = "<memory>", scope = "project") {
|
|
8303
|
+
const split = splitPlanProtocolBlock(text, sourcePath, scope);
|
|
8304
|
+
const lineEnding = preferredMarkdownLineEnding(text);
|
|
8305
|
+
const normalizedBlock = normalizeMarkdownLineEndings(block).replaceAll("\n", lineEnding);
|
|
8306
|
+
if (split.block !== void 0)
|
|
8307
|
+
return split.before + normalizedBlock + split.after;
|
|
8308
|
+
if (text === "")
|
|
8309
|
+
return normalizedBlock;
|
|
8310
|
+
let before = text;
|
|
8311
|
+
if (!before.endsWith("\n"))
|
|
8312
|
+
before += lineEnding;
|
|
8313
|
+
if (!before.endsWith(`${lineEnding}${lineEnding}`))
|
|
8314
|
+
before += lineEnding;
|
|
8315
|
+
return before + normalizedBlock;
|
|
8316
|
+
}
|
|
8317
|
+
var PLAN_PROTOCOL_VERSION, PLAN_PROTOCOL_USER_VERSION, PLAN_PROTOCOL_TEXT, PLAN_PROTOCOL_TEXT_USER, PLAN_PROTOCOL_USER_BLOCK_END, PLAN_PROTOCOL_BLOCK_END, LEGACY_PLAN_PROTOCOL_TEXT, KNOWN_PROTOCOL_TEXT, KNOWN_USER_PROTOCOL_TEXT, BLOCK_START, USER_BLOCK_START;
|
|
8291
8318
|
var init_plan_protocol = __esm({
|
|
8292
8319
|
"packages/core/dist/plan-protocol.js"() {
|
|
8293
8320
|
"use strict";
|
|
8294
8321
|
PLAN_PROTOCOL_VERSION = 1;
|
|
8322
|
+
PLAN_PROTOCOL_USER_VERSION = 1;
|
|
8295
8323
|
PLAN_PROTOCOL_TEXT = `Wingman plan protocol v1 \u2014 a behavioral convention, not a gate. Wingman only reads; it never replies to you.
|
|
8296
8324
|
- The project root is the directory that contains this instruction file (for Claude Code: the parent of \`.claude/\`).
|
|
8297
8325
|
- Before starting work, read \`<project root>/.wingman/plan.md\`. If it does not exist, create it: a \`# Title\` line, then a nested checkbox tree of steps, each step with an indented \`Verify:\` line describing how it will be checked.
|
|
@@ -8300,13 +8328,159 @@ var init_plan_protocol = __esm({
|
|
|
8300
8328
|
- Keep your in-session todo list as sub-steps of the \`[/]\` step; do not copy the whole file into it.
|
|
8301
8329
|
- Never put secrets, credentials, or personal data in the plan.
|
|
8302
8330
|
`;
|
|
8331
|
+
PLAN_PROTOCOL_TEXT_USER = PLAN_PROTOCOL_TEXT.replace(/^- The project root .*$/mu, "- The project root is the nearest git root containing the current working directory, or the current working directory when there is no git root. If the current working directory is the user\u2019s home directory, you MUST NOT create a plan file. Only multi-step tasks use the plan workflow below; single-turn questions do not create or update a plan file.");
|
|
8332
|
+
PLAN_PROTOCOL_USER_BLOCK_END = "<!-- <<< wingman plan protocol user <<< -->";
|
|
8303
8333
|
PLAN_PROTOCOL_BLOCK_END = "<!-- <<< wingman plan protocol <<< -->";
|
|
8304
8334
|
LEGACY_PLAN_PROTOCOL_TEXT = "Wingman plan protocol v0 \u2014 legacy fixture text.\n";
|
|
8305
8335
|
KNOWN_PROTOCOL_TEXT = /* @__PURE__ */ new Map([
|
|
8306
8336
|
[0, LEGACY_PLAN_PROTOCOL_TEXT],
|
|
8307
8337
|
[PLAN_PROTOCOL_VERSION, PLAN_PROTOCOL_TEXT]
|
|
8308
8338
|
]);
|
|
8339
|
+
KNOWN_USER_PROTOCOL_TEXT = /* @__PURE__ */ new Map([[PLAN_PROTOCOL_USER_VERSION, PLAN_PROTOCOL_TEXT_USER]]);
|
|
8309
8340
|
BLOCK_START = /<!-- >>> wingman plan protocol v(\d+) >>> -->/gu;
|
|
8341
|
+
USER_BLOCK_START = /<!-- >>> wingman plan protocol user v(\d+) >>> -->/gu;
|
|
8342
|
+
}
|
|
8343
|
+
});
|
|
8344
|
+
|
|
8345
|
+
// packages/core/dist/plan-protocol-user.js
|
|
8346
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
8347
|
+
import { basename as basename2, dirname as dirname2, join as join2 } from "node:path";
|
|
8348
|
+
function readTarget(targetPath2) {
|
|
8349
|
+
if (!existsSync(targetPath2))
|
|
8350
|
+
return void 0;
|
|
8351
|
+
const bytes = readFileSync(targetPath2);
|
|
8352
|
+
decodeUtf8Strict2(bytes, targetPath2);
|
|
8353
|
+
const text = bytes.toString("utf8");
|
|
8354
|
+
const split = splitPlanProtocolBlock(text, targetPath2, "user");
|
|
8355
|
+
const identity = split.block === void 0 ? void 0 : inspectPlanProtocolBlock(split.block, "user");
|
|
8356
|
+
return { bytes, text, split, identity };
|
|
8357
|
+
}
|
|
8358
|
+
function statusPlanProtocolUser(targetPath2) {
|
|
8359
|
+
try {
|
|
8360
|
+
const identity = readTarget(targetPath2)?.identity;
|
|
8361
|
+
return {
|
|
8362
|
+
targetPath: targetPath2,
|
|
8363
|
+
state: identity === void 0 ? "missing" : identity.kind === "current" ? "installed" : "modified",
|
|
8364
|
+
...identity?.version !== void 0 ? { version: identity.version } : {},
|
|
8365
|
+
...identity?.kind === "modified" ? { reason: "\u7528\u6237\u7EA7\u53D7\u7BA1\u5757\u5DF2\u88AB\u4FEE\u6539" } : {}
|
|
8366
|
+
};
|
|
8367
|
+
} catch (error) {
|
|
8368
|
+
return { targetPath: targetPath2, state: "modified", reason: error.message };
|
|
8369
|
+
}
|
|
8370
|
+
}
|
|
8371
|
+
function installPlanProtocolUser(paths3) {
|
|
8372
|
+
const existing = readTarget(paths3.targetPath);
|
|
8373
|
+
assertKnown(existing, paths3.targetPath);
|
|
8374
|
+
const before = existing?.text ?? "";
|
|
8375
|
+
if (existing?.identity !== void 0) {
|
|
8376
|
+
return result(paths3.targetPath, "install", "installed", before, before, true, false);
|
|
8377
|
+
}
|
|
8378
|
+
const statePath2 = snapshotPath(paths3);
|
|
8379
|
+
readSnapshot(statePath2, paths3.targetPath);
|
|
8380
|
+
const block = buildPlanProtocolBlock(PLAN_PROTOCOL_USER_VERSION, void 0, "user");
|
|
8381
|
+
const after = mergePlanProtocolBlock(before, block, paths3.targetPath, "user");
|
|
8382
|
+
const backupDir = nextBackupDir(paths3.homeDir);
|
|
8383
|
+
if (!paths3.dryRun) {
|
|
8384
|
+
backupTarget(backupDir, paths3.targetPath, existing?.bytes);
|
|
8385
|
+
const snapshot = {
|
|
8386
|
+
version: 1,
|
|
8387
|
+
targetPath: paths3.targetPath,
|
|
8388
|
+
installedRemainderSha256: sha256Hex(splitPlanProtocolBlock(after, paths3.targetPath, "user").remainder),
|
|
8389
|
+
original: existing === void 0 ? { existed: false } : { existed: true, base64: existing.bytes.toString("base64") }
|
|
8390
|
+
};
|
|
8391
|
+
mkdirSync(dirname2(statePath2), { recursive: true });
|
|
8392
|
+
writeFileSync(statePath2, `${JSON.stringify(snapshot, null, 2)}
|
|
8393
|
+
`);
|
|
8394
|
+
mkdirSync(dirname2(paths3.targetPath), { recursive: true });
|
|
8395
|
+
writeFileSync(paths3.targetPath, after);
|
|
8396
|
+
}
|
|
8397
|
+
return {
|
|
8398
|
+
...result(paths3.targetPath, "install", "missing", before, after, true, true),
|
|
8399
|
+
state: "installed",
|
|
8400
|
+
version: PLAN_PROTOCOL_USER_VERSION,
|
|
8401
|
+
backupDir
|
|
8402
|
+
};
|
|
8403
|
+
}
|
|
8404
|
+
function uninstallPlanProtocolUser(paths3) {
|
|
8405
|
+
const existing = readTarget(paths3.targetPath);
|
|
8406
|
+
assertKnown(existing, paths3.targetPath);
|
|
8407
|
+
const before = existing?.text ?? "";
|
|
8408
|
+
if (existing?.identity === void 0) {
|
|
8409
|
+
return result(paths3.targetPath, "uninstall", "missing", before, before, existing !== void 0, false);
|
|
8410
|
+
}
|
|
8411
|
+
const statePath2 = snapshotPath(paths3);
|
|
8412
|
+
const snapshot = readSnapshot(statePath2, paths3.targetPath);
|
|
8413
|
+
const canRestore = snapshot !== void 0 && sha256Hex(existing.split.remainder) === snapshot.installedRemainderSha256;
|
|
8414
|
+
const restored = canRestore && snapshot.original.existed ? Buffer.from(snapshot.original.base64 ?? "", "base64") : void 0;
|
|
8415
|
+
const afterExists = canRestore ? snapshot.original.existed : existing.split.remainder !== "";
|
|
8416
|
+
const after = afterExists ? restored?.toString("utf8") ?? existing.split.remainder : "";
|
|
8417
|
+
const backupDir = nextBackupDir(paths3.homeDir);
|
|
8418
|
+
if (!paths3.dryRun) {
|
|
8419
|
+
backupTarget(backupDir, paths3.targetPath, existing.bytes);
|
|
8420
|
+
if (afterExists)
|
|
8421
|
+
writeFileSync(paths3.targetPath, restored ?? after);
|
|
8422
|
+
else
|
|
8423
|
+
rmSync(paths3.targetPath);
|
|
8424
|
+
rmSync(statePath2, { force: true });
|
|
8425
|
+
}
|
|
8426
|
+
return {
|
|
8427
|
+
...result(paths3.targetPath, "uninstall", "installed", before, after, afterExists, true),
|
|
8428
|
+
state: "missing",
|
|
8429
|
+
backupDir,
|
|
8430
|
+
restoredOriginal: canRestore
|
|
8431
|
+
};
|
|
8432
|
+
}
|
|
8433
|
+
function assertKnown(existing, targetPath2) {
|
|
8434
|
+
if (existing?.identity !== void 0 && existing.identity.kind !== "current") {
|
|
8435
|
+
throw new Error(`${targetPath2}: \u7528\u6237\u7EA7\u53D7\u7BA1\u5757\u5DF2\u88AB\u4FEE\u6539\u6216\u7248\u672C\u672A\u77E5\uFF0C\u62D2\u5199\u5E76\u4FDD\u7559\u7528\u6237\u5185\u5BB9`);
|
|
8436
|
+
}
|
|
8437
|
+
}
|
|
8438
|
+
function result(targetPath2, operation, previousState, before, after, afterExists, changed) {
|
|
8439
|
+
return {
|
|
8440
|
+
targetPath: targetPath2,
|
|
8441
|
+
operation,
|
|
8442
|
+
previousState,
|
|
8443
|
+
state: previousState,
|
|
8444
|
+
before,
|
|
8445
|
+
after,
|
|
8446
|
+
afterExists,
|
|
8447
|
+
changed,
|
|
8448
|
+
effectiveAt: "next_session",
|
|
8449
|
+
totalBytes: Buffer.byteLength(after)
|
|
8450
|
+
};
|
|
8451
|
+
}
|
|
8452
|
+
function snapshotPath(paths3) {
|
|
8453
|
+
return join2(paths3.homeDir, ".wingman", "state", `plan-protocol-user-${sha256Hex(paths3.targetPath)}.json`);
|
|
8454
|
+
}
|
|
8455
|
+
function readSnapshot(statePath2, targetPath2) {
|
|
8456
|
+
if (!existsSync(statePath2))
|
|
8457
|
+
return void 0;
|
|
8458
|
+
try {
|
|
8459
|
+
const value = JSON.parse(readFileSync(statePath2, "utf8"));
|
|
8460
|
+
if (value.version === 1 && value.targetPath === targetPath2 && typeof value.installedRemainderSha256 === "string" && /^[a-f0-9]{64}$/u.test(value.installedRemainderSha256) && typeof value.original?.existed === "boolean" && (value.original.existed ? typeof value.original.base64 === "string" && Buffer.from(value.original.base64, "base64").toString("base64") === value.original.base64 : value.original.base64 === void 0)) {
|
|
8461
|
+
return value;
|
|
8462
|
+
}
|
|
8463
|
+
} catch {
|
|
8464
|
+
}
|
|
8465
|
+
throw new Error(`\u7528\u6237\u7EA7\u534F\u8BAE\u5FEB\u7167\u683C\u5F0F\u672A\u77E5(${statePath2})\uFF0C\u62D2\u5199\u5E76\u4FDD\u7559\u7528\u6237\u5185\u5BB9`);
|
|
8466
|
+
}
|
|
8467
|
+
function nextBackupDir(homeDir) {
|
|
8468
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
8469
|
+
const root = join2(homeDir, ".wingman", "backups");
|
|
8470
|
+
let dir = join2(root, stamp);
|
|
8471
|
+
for (let n = 2; existsSync(dir); n += 1)
|
|
8472
|
+
dir = join2(root, `${stamp}-${n}`);
|
|
8473
|
+
return dir;
|
|
8474
|
+
}
|
|
8475
|
+
function backupTarget(backupDir, targetPath2, bytes) {
|
|
8476
|
+
mkdirSync(backupDir, { recursive: true });
|
|
8477
|
+
if (bytes !== void 0)
|
|
8478
|
+
writeFileSync(join2(backupDir, basename2(targetPath2)), bytes);
|
|
8479
|
+
}
|
|
8480
|
+
var init_plan_protocol_user = __esm({
|
|
8481
|
+
"packages/core/dist/plan-protocol-user.js"() {
|
|
8482
|
+
"use strict";
|
|
8483
|
+
init_plan_protocol();
|
|
8310
8484
|
}
|
|
8311
8485
|
});
|
|
8312
8486
|
|
|
@@ -8492,6 +8666,7 @@ var init_dist = __esm({
|
|
|
8492
8666
|
"use strict";
|
|
8493
8667
|
init_feedback_url();
|
|
8494
8668
|
init_plan_protocol();
|
|
8669
|
+
init_plan_protocol_user();
|
|
8495
8670
|
init_refscan();
|
|
8496
8671
|
SLOT_IDS = ["base", "rules", "skills", "tools", "gates", "history"];
|
|
8497
8672
|
HARNESS_IDS = ["cc", "codex", "dsh"];
|
|
@@ -8521,7 +8696,7 @@ var init_dist = __esm({
|
|
|
8521
8696
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
8522
8697
|
import { randomBytes } from "node:crypto";
|
|
8523
8698
|
import { mkdir as mkdir2, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
8524
|
-
import { dirname as
|
|
8699
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, relative as relative2 } from "node:path";
|
|
8525
8700
|
function buildToggleBlock(instanceId, flags) {
|
|
8526
8701
|
const lines2 = [`${TOGGLE_BEGIN_PREFIX}${instanceId}${TOGGLE_BEGIN_SUFFIX}`];
|
|
8527
8702
|
if (flags.fileCreated)
|
|
@@ -8782,15 +8957,15 @@ async function planDshToggle(action, dump, options) {
|
|
|
8782
8957
|
if (row.id === DSH_HOOK_ROW_ID && row.name === DSH_HOOKS_PACKAGE) {
|
|
8783
8958
|
throw new Error(`\u300C${row.name}\u300D(${row.id})\u7531 Wingman \u5B9E\u51B5\u63A5\u7EBF(live hooks \u5757)\u5F15\u5165,\u8BF7\u7528 \`wingman hook uninstall dsh\` \u7BA1\u7406,\u4E0D\u8D70\u5F00\u5173`);
|
|
8784
8959
|
}
|
|
8785
|
-
const
|
|
8786
|
-
const buffer = await readIfExists(
|
|
8787
|
-
const text = buffer === void 0 ? void 0 : decodeUtf8Strict(buffer,
|
|
8788
|
-
const blocks = text === void 0 ? [] : findToggleBlocks(text,
|
|
8960
|
+
const paths3 = resolveDshHookPaths(options);
|
|
8961
|
+
const buffer = await readIfExists(paths3.patchFile);
|
|
8962
|
+
const text = buffer === void 0 ? void 0 : decodeUtf8Strict(buffer, paths3.patchFile);
|
|
8963
|
+
const blocks = text === void 0 ? [] : findToggleBlocks(text, paths3.patchFile);
|
|
8789
8964
|
const myBlock = blocks.find((b) => b.instanceId === row.id);
|
|
8790
|
-
const entriesAll = text === void 0 ? [] : parsePatchEntries(text,
|
|
8965
|
+
const entriesAll = text === void 0 ? [] : parsePatchEntries(text, paths3.patchFile);
|
|
8791
8966
|
const outsideToggle = text === void 0 ? "" : stripAllToggleBlocks(text, blocks);
|
|
8792
|
-
const entriesOutsideToggle = text === void 0 ? [] : parsePatchEntries(outsideToggle,
|
|
8793
|
-
const entriesUser = text === void 0 ? [] : parsePatchEntries(stripHooksBlocks(outsideToggle),
|
|
8967
|
+
const entriesOutsideToggle = text === void 0 ? [] : parsePatchEntries(outsideToggle, paths3.patchFile);
|
|
8968
|
+
const entriesUser = text === void 0 ? [] : parsePatchEntries(stripHooksBlocks(outsideToggle), paths3.patchFile);
|
|
8794
8969
|
const refInUser = referencesInstanceId(entriesUser, row.id);
|
|
8795
8970
|
const refInHooks = !refInUser && referencesInstanceId(entriesOutsideToggle, row.id);
|
|
8796
8971
|
if (refInHooks) {
|
|
@@ -8802,36 +8977,36 @@ async function planDshToggle(action, dump, options) {
|
|
|
8802
8977
|
throw new Error(`\u300C${row.name}\u300D(${row.id})\u5DF2\u7531 Wingman \u5173\u95ED(dsh \u4E0B\u6B21\u542F\u52A8\u751F\u6548);\u5982\u9700\u6062\u590D\u8BF7 toggle on`);
|
|
8803
8978
|
}
|
|
8804
8979
|
if (refInUser) {
|
|
8805
|
-
throw new Error(`${
|
|
8980
|
+
throw new Error(`${paths3.patchFile} \u5DF2\u6709\u7528\u6237\u81EA\u5DF1\u7684 ${row.id} \u6761\u76EE,\u4E0D\u731C\u5408\u5E76:\u8BF7\u624B\u5DE5\u5904\u7406\u8BE5\u6761\u76EE\u540E\u518D\u8BD5`);
|
|
8806
8981
|
}
|
|
8807
8982
|
if (row.disabled === true) {
|
|
8808
8983
|
throw new Error(`\u300C${row.name}\u300D(${row.id})\u5DF2\u5728 ${item.source} \u5C42\u88AB\u7981\u7528(\u539F\u751F\u7981\u7528\u975E Wingman \u6240\u8F96),\u65E0\u9700\u518D\u5173`);
|
|
8809
8984
|
}
|
|
8810
8985
|
const composed = composeToggleOff(text, row.id, entriesAll.length);
|
|
8811
8986
|
const expected = JSON.stringify([...entriesAll, { id: row.id, disabled: true }]);
|
|
8812
|
-
if (JSON.stringify(parsePatchEntries(composed.after,
|
|
8813
|
-
throw new Error(`\u62D2\u5199:${
|
|
8987
|
+
if (JSON.stringify(parsePatchEntries(composed.after, paths3.patchFile)) !== expected) {
|
|
8988
|
+
throw new Error(`\u62D2\u5199:${paths3.patchFile} \u8FFD\u52A0\u540E\u5F62\u72B6\u6821\u9A8C\u5931\u8D25(\u539F\u6587\u4EF6\u5F62\u6001\u65E0\u6CD5\u5B89\u5168\u8FFD\u52A0),\u4E0D\u731C`);
|
|
8814
8989
|
}
|
|
8815
|
-
change = composed.kind === "create" || text === void 0 ? { file:
|
|
8990
|
+
change = composed.kind === "create" || text === void 0 ? { file: paths3.patchFile, kind: "create", after: composed.after } : { file: paths3.patchFile, kind: "modify", before: text, after: composed.after };
|
|
8816
8991
|
} else {
|
|
8817
8992
|
if (myBlock === void 0 || text === void 0) {
|
|
8818
8993
|
if (refInUser) {
|
|
8819
|
-
throw new Error(`${
|
|
8994
|
+
throw new Error(`${paths3.patchFile} \u5DF2\u6709\u7528\u6237\u81EA\u5DF1\u7684 ${row.id} \u6761\u76EE,\u4E0D\u731C\u5408\u5E76:\u8BF7\u624B\u5DE5\u5904\u7406\u8BE5\u6761\u76EE\u540E\u518D\u8BD5`);
|
|
8820
8995
|
}
|
|
8821
8996
|
if (row.disabled === true) {
|
|
8822
8997
|
throw new Error(`\u300C${row.name}\u300D(${row.id})\u5728 ${item.source} \u5C42\u88AB\u539F\u751F\u7981\u7528,\u975E Wingman \u6240\u8F96:\u8BF7\u5230\u8BE5\u5C42(bundle/profile \u914D\u7F6E)\u4FEE\u6539`);
|
|
8823
8998
|
}
|
|
8824
8999
|
throw new Error(`\u300C${row.name}\u300D(${row.id})\u5DF2\u662F\u542F\u7528\u72B6\u6001,\u65E0\u9700 toggle on`);
|
|
8825
9000
|
}
|
|
8826
|
-
const composed = composeToggleOn(text, myBlock,
|
|
8827
|
-
change = composed.kind === "delete" || composed.after === void 0 ? { file:
|
|
9001
|
+
const composed = composeToggleOn(text, myBlock, paths3.patchFile);
|
|
9002
|
+
change = composed.kind === "delete" || composed.after === void 0 ? { file: paths3.patchFile, kind: "delete", before: text } : { file: paths3.patchFile, kind: "modify", before: text, after: composed.after };
|
|
8828
9003
|
}
|
|
8829
9004
|
return {
|
|
8830
9005
|
harness: "dsh",
|
|
8831
9006
|
action: toggle,
|
|
8832
9007
|
writes: [change],
|
|
8833
|
-
backupDir:
|
|
8834
|
-
references: scanDshReferences(
|
|
9008
|
+
backupDir: join3(paths3.backupsRoot, backupDirName()),
|
|
9009
|
+
references: scanDshReferences(paths3.patchFile, text, dump, row),
|
|
8835
9010
|
// 生效时机:patch 层在 boot 时组装(composeProfile),保证下次启动生效;钉定版本
|
|
8836
9011
|
// 还会 watchUserPatches 热重载家目录层,但该监听失败被静默吞掉(suppressShutdownError)
|
|
8837
9012
|
// 且热拔插行为无兼容承诺 → 按宪法取保守值 next_session,如实不夸大。
|
|
@@ -8864,39 +9039,39 @@ function validatePlanShape(plan, patchFile, backupsRoot) {
|
|
|
8864
9039
|
}
|
|
8865
9040
|
async function applyDshToggle(plan, options) {
|
|
8866
9041
|
try {
|
|
8867
|
-
const
|
|
8868
|
-
const { change } = validatePlanShape(plan,
|
|
8869
|
-
const buffer = await readIfExists(
|
|
9042
|
+
const paths3 = resolveDshHookPaths(options);
|
|
9043
|
+
const { change } = validatePlanShape(plan, paths3.patchFile, paths3.backupsRoot);
|
|
9044
|
+
const buffer = await readIfExists(paths3.patchFile);
|
|
8870
9045
|
if (change.kind === "create") {
|
|
8871
9046
|
if (buffer !== void 0) {
|
|
8872
9047
|
return {
|
|
8873
9048
|
ok: false,
|
|
8874
|
-
error: `${
|
|
9049
|
+
error: `${paths3.patchFile} \u5728 plan \u4E4B\u540E\u88AB\u521B\u5EFA,\u4E0E plan \u524D\u63D0\u4E0D\u7B26:\u8BF7\u91CD\u65B0 plan`
|
|
8875
9050
|
};
|
|
8876
9051
|
}
|
|
8877
9052
|
} else {
|
|
8878
9053
|
if (buffer === void 0) {
|
|
8879
9054
|
return {
|
|
8880
9055
|
ok: false,
|
|
8881
|
-
error: `${
|
|
9056
|
+
error: `${paths3.patchFile} \u5728 plan \u4E4B\u540E\u88AB\u5220\u9664,\u4E0E plan \u524D\u63D0\u4E0D\u7B26:\u8BF7\u91CD\u65B0 plan`
|
|
8882
9057
|
};
|
|
8883
9058
|
}
|
|
8884
9059
|
if (!buffer.equals(Buffer3.from(change.before ?? "", "utf8"))) {
|
|
8885
9060
|
return {
|
|
8886
9061
|
ok: false,
|
|
8887
|
-
error: `${
|
|
9062
|
+
error: `${paths3.patchFile} \u5728 plan \u4E4B\u540E\u88AB\u6539\u52A8,\u4E0E plan \u5FEB\u7167\u4E0D\u4E00\u81F4:\u8BF7\u91CD\u65B0 plan`
|
|
8888
9063
|
};
|
|
8889
9064
|
}
|
|
8890
9065
|
}
|
|
8891
9066
|
await mkdir2(plan.backupDir, { recursive: true });
|
|
8892
9067
|
if (buffer !== void 0) {
|
|
8893
|
-
await writeFile2(
|
|
9068
|
+
await writeFile2(join3(plan.backupDir, "cordis.patch.yml"), buffer);
|
|
8894
9069
|
}
|
|
8895
9070
|
if (change.kind === "delete") {
|
|
8896
|
-
await rm2(
|
|
9071
|
+
await rm2(paths3.patchFile);
|
|
8897
9072
|
} else {
|
|
8898
|
-
await mkdir2(
|
|
8899
|
-
await writeFile2(
|
|
9073
|
+
await mkdir2(dirname3(paths3.patchFile), { recursive: true });
|
|
9074
|
+
await writeFile2(paths3.patchFile, change.after ?? "", "utf8");
|
|
8900
9075
|
}
|
|
8901
9076
|
return { ok: true, backupDir: plan.backupDir };
|
|
8902
9077
|
} catch (error) {
|
|
@@ -8925,55 +9100,55 @@ var init_toggle = __esm({
|
|
|
8925
9100
|
|
|
8926
9101
|
// packages/adapter-dsh/dist/protocol.js
|
|
8927
9102
|
import { execFileSync } from "node:child_process";
|
|
8928
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
9103
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
8929
9104
|
import { homedir as homedir2 } from "node:os";
|
|
8930
|
-
import { basename as
|
|
9105
|
+
import { basename as basename3, dirname as dirname4, join as join4, resolve } from "node:path";
|
|
8931
9106
|
function protocolStatusDsh(options) {
|
|
8932
|
-
const
|
|
8933
|
-
if (!
|
|
8934
|
-
return status(
|
|
9107
|
+
const paths3 = resolveOptions(options);
|
|
9108
|
+
if (!existsSync2(paths3.targetPath))
|
|
9109
|
+
return status(paths3.targetPath, "not_installed", options);
|
|
8935
9110
|
try {
|
|
8936
|
-
const file = readAgents(
|
|
9111
|
+
const file = readAgents(paths3.targetPath);
|
|
8937
9112
|
if (file.identity === void 0)
|
|
8938
|
-
return status(
|
|
9113
|
+
return status(paths3.targetPath, "not_installed", options);
|
|
8939
9114
|
const state = stateForIdentity(file.identity);
|
|
8940
|
-
return status(
|
|
9115
|
+
return status(paths3.targetPath, state, options, file.identity);
|
|
8941
9116
|
} catch (error) {
|
|
8942
|
-
return status(
|
|
9117
|
+
return status(paths3.targetPath, "invalid", options, void 0, error.message);
|
|
8943
9118
|
}
|
|
8944
9119
|
}
|
|
8945
9120
|
function installProtocolDsh(options) {
|
|
8946
|
-
const
|
|
8947
|
-
const existing =
|
|
9121
|
+
const paths3 = resolveOptions(options);
|
|
9122
|
+
const existing = existsSync2(paths3.targetPath) ? readAgents(paths3.targetPath) : void 0;
|
|
8948
9123
|
const previousState = stateForIdentity(existing?.identity);
|
|
8949
9124
|
if (previousState === "installed") {
|
|
8950
|
-
return overlayLoadState(
|
|
9125
|
+
return overlayLoadState(result2(paths3.targetPath, "install", false, previousState, existing?.text ?? "", true), options);
|
|
8951
9126
|
}
|
|
8952
9127
|
if (previousState === "modified")
|
|
8953
|
-
throw modifiedError(
|
|
9128
|
+
throw modifiedError(paths3.targetPath, "\u5B89\u88C5");
|
|
8954
9129
|
const before = existing?.text ?? "";
|
|
8955
9130
|
const lineEnding = preferredMarkdownLineEnding(before);
|
|
8956
9131
|
const block = buildPlanProtocolBlock().replaceAll("\n", lineEnding);
|
|
8957
9132
|
const after = existing?.split.block ? existing.split.before + block + existing.split.after : appendBlock(before, block, lineEnding);
|
|
8958
|
-
const installedRemainder = splitPlanProtocolBlock(after,
|
|
8959
|
-
const backupDir =
|
|
8960
|
-
if (!
|
|
8961
|
-
const prior = readState2(
|
|
8962
|
-
|
|
8963
|
-
writeState2(
|
|
9133
|
+
const installedRemainder = splitPlanProtocolBlock(after, paths3.targetPath).remainder;
|
|
9134
|
+
const backupDir = nextBackupDir2(paths3.homeDir);
|
|
9135
|
+
if (!paths3.dryRun) {
|
|
9136
|
+
const prior = readState2(paths3.statePath, paths3.targetPath);
|
|
9137
|
+
backupTarget2(backupDir, paths3.targetPath, existing?.bytes);
|
|
9138
|
+
writeState2(paths3.statePath, {
|
|
8964
9139
|
version: 1,
|
|
8965
|
-
projectDir:
|
|
8966
|
-
targetPath:
|
|
9140
|
+
projectDir: paths3.projectDir,
|
|
9141
|
+
targetPath: paths3.targetPath,
|
|
8967
9142
|
protocolVersion: PLAN_PROTOCOL_VERSION,
|
|
8968
9143
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8969
9144
|
backupDir,
|
|
8970
9145
|
installedRemainderSha256: sha256Hex(installedRemainder),
|
|
8971
9146
|
original: prior?.original ?? (existing === void 0 ? { existed: false } : { existed: true, base64: existing.bytes.toString("base64") })
|
|
8972
9147
|
});
|
|
8973
|
-
|
|
9148
|
+
writeFileSync2(paths3.targetPath, after);
|
|
8974
9149
|
}
|
|
8975
9150
|
return overlayLoadState({
|
|
8976
|
-
...
|
|
9151
|
+
...result2(paths3.targetPath, "install", true, previousState, before, true),
|
|
8977
9152
|
state: "installed",
|
|
8978
9153
|
version: PLAN_PROTOCOL_VERSION,
|
|
8979
9154
|
after,
|
|
@@ -8982,33 +9157,33 @@ function installProtocolDsh(options) {
|
|
|
8982
9157
|
}, options);
|
|
8983
9158
|
}
|
|
8984
9159
|
function uninstallProtocolDsh(options) {
|
|
8985
|
-
const
|
|
8986
|
-
if (!
|
|
8987
|
-
return
|
|
9160
|
+
const paths3 = resolveOptions(options);
|
|
9161
|
+
if (!existsSync2(paths3.targetPath)) {
|
|
9162
|
+
return result2(paths3.targetPath, "uninstall", false, "not_installed", "", false);
|
|
8988
9163
|
}
|
|
8989
|
-
const existing = readAgents(
|
|
9164
|
+
const existing = readAgents(paths3.targetPath);
|
|
8990
9165
|
if (existing.identity === void 0) {
|
|
8991
|
-
return
|
|
9166
|
+
return result2(paths3.targetPath, "uninstall", false, "not_installed", existing.text, true);
|
|
8992
9167
|
}
|
|
8993
9168
|
const previousState = stateForIdentity(existing.identity);
|
|
8994
9169
|
if (previousState === "modified")
|
|
8995
|
-
throw modifiedError(
|
|
8996
|
-
const state = readState2(
|
|
9170
|
+
throw modifiedError(paths3.targetPath, "\u5378\u8F7D");
|
|
9171
|
+
const state = readState2(paths3.statePath, paths3.targetPath);
|
|
8997
9172
|
const canRestore = state !== void 0 && sha256Hex(existing.split.remainder) === state.installedRemainderSha256;
|
|
8998
9173
|
const restored = canRestore ? originalBytes(state) : void 0;
|
|
8999
9174
|
const deleteTarget = canRestore ? state?.original.existed === false : existing.split.remainder.trim() === "";
|
|
9000
9175
|
const after = deleteTarget ? "" : restored?.toString("utf8") ?? existing.split.remainder;
|
|
9001
|
-
const backupDir =
|
|
9002
|
-
if (!
|
|
9003
|
-
|
|
9176
|
+
const backupDir = nextBackupDir2(paths3.homeDir);
|
|
9177
|
+
if (!paths3.dryRun) {
|
|
9178
|
+
backupTarget2(backupDir, paths3.targetPath, existing.bytes);
|
|
9004
9179
|
if (deleteTarget)
|
|
9005
|
-
|
|
9180
|
+
rmSync2(paths3.targetPath, { force: true });
|
|
9006
9181
|
else
|
|
9007
|
-
|
|
9008
|
-
|
|
9182
|
+
writeFileSync2(paths3.targetPath, restored ?? existing.split.remainder);
|
|
9183
|
+
rmSync2(paths3.statePath, { force: true });
|
|
9009
9184
|
}
|
|
9010
9185
|
return {
|
|
9011
|
-
...
|
|
9186
|
+
...result2(paths3.targetPath, "uninstall", true, previousState, existing.text, !deleteTarget),
|
|
9012
9187
|
state: "not_installed",
|
|
9013
9188
|
message: canRestore ? `${SHARED_MESSAGE}\uFF1B\u5378\u8F7D\u540C\u65F6\u5F71\u54CD Codex \u4E0E dsh` : `${SHARED_MESSAGE}\uFF1B\u5378\u8F7D\u540C\u65F6\u5F71\u54CD Codex \u4E0E dsh\uFF1B\u5DF2\u4FDD\u7559\u7528\u6237\u6539\u52A8`,
|
|
9014
9189
|
after,
|
|
@@ -9020,17 +9195,17 @@ function uninstallProtocolDsh(options) {
|
|
|
9020
9195
|
function resolveOptions(options) {
|
|
9021
9196
|
const homeDir = resolve(options?.homeDir ?? homedir2());
|
|
9022
9197
|
const projectDir = resolve(options?.projectDir ?? process.cwd());
|
|
9023
|
-
const targetPath2 =
|
|
9198
|
+
const targetPath2 = join4(projectDir, "AGENTS.md");
|
|
9024
9199
|
return {
|
|
9025
9200
|
homeDir,
|
|
9026
9201
|
projectDir,
|
|
9027
9202
|
targetPath: targetPath2,
|
|
9028
|
-
statePath:
|
|
9203
|
+
statePath: join4(homeDir, ".wingman", "state", `plan-protocol-agents-${sha256Hex(projectDir)}.json`),
|
|
9029
9204
|
dryRun: options?.dryRun ?? false
|
|
9030
9205
|
};
|
|
9031
9206
|
}
|
|
9032
9207
|
function readAgents(targetPath2) {
|
|
9033
|
-
const bytes =
|
|
9208
|
+
const bytes = readFileSync2(targetPath2);
|
|
9034
9209
|
const text = decodeUtf8Strict2(bytes, targetPath2);
|
|
9035
9210
|
let split;
|
|
9036
9211
|
try {
|
|
@@ -9078,7 +9253,7 @@ function status(targetPath2, state, options, identity, reason) {
|
|
|
9078
9253
|
...reason !== void 0 ? { reason } : {}
|
|
9079
9254
|
};
|
|
9080
9255
|
}
|
|
9081
|
-
function
|
|
9256
|
+
function result2(targetPath2, operation, changed, previousState, before, afterExists) {
|
|
9082
9257
|
return {
|
|
9083
9258
|
harness: "dsh",
|
|
9084
9259
|
state: previousState,
|
|
@@ -9112,7 +9287,7 @@ function agentInstructionsDisabled(options) {
|
|
|
9112
9287
|
if (options?.dumpConfigText !== void 0)
|
|
9113
9288
|
text = options.dumpConfigText;
|
|
9114
9289
|
else if (options?.dumpConfigPath !== void 0)
|
|
9115
|
-
text =
|
|
9290
|
+
text = readFileSync2(options.dumpConfigPath, "utf8");
|
|
9116
9291
|
else {
|
|
9117
9292
|
text = execFileSync("dsh", ["--profile", options?.profile ?? "web", "--dump-config"], {
|
|
9118
9293
|
encoding: "utf8",
|
|
@@ -9129,38 +9304,41 @@ function agentInstructionsDisabled(options) {
|
|
|
9129
9304
|
function modifiedError(targetPath2, operation) {
|
|
9130
9305
|
return new Error(`${targetPath2}: \u53D7\u7BA1\u5757\u5DF2\u88AB\u4FEE\u6539\uFF0C\u62D2\u7EDD${operation}\u5E76\u4FDD\u7559\u7528\u6237\u5185\u5BB9`);
|
|
9131
9306
|
}
|
|
9132
|
-
function
|
|
9307
|
+
function nextBackupDir2(homeDir) {
|
|
9133
9308
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
9134
|
-
const root =
|
|
9135
|
-
let dir =
|
|
9136
|
-
for (let n = 2;
|
|
9137
|
-
dir =
|
|
9309
|
+
const root = join4(homeDir, ".wingman", "backups");
|
|
9310
|
+
let dir = join4(root, stamp);
|
|
9311
|
+
for (let n = 2; existsSync2(dir); n += 1)
|
|
9312
|
+
dir = join4(root, `${stamp}-${n}`);
|
|
9138
9313
|
return dir;
|
|
9139
9314
|
}
|
|
9140
|
-
function
|
|
9141
|
-
|
|
9315
|
+
function backupTarget2(backupDir, targetPath2, bytes) {
|
|
9316
|
+
mkdirSync2(backupDir, { recursive: true });
|
|
9142
9317
|
if (bytes !== void 0)
|
|
9143
|
-
|
|
9318
|
+
writeFileSync2(join4(backupDir, basename3(targetPath2)), bytes);
|
|
9144
9319
|
}
|
|
9145
9320
|
function readState2(statePath2, targetPath2) {
|
|
9146
|
-
if (!
|
|
9321
|
+
if (!existsSync2(statePath2))
|
|
9147
9322
|
return void 0;
|
|
9148
9323
|
try {
|
|
9149
|
-
const value = JSON.parse(
|
|
9324
|
+
const value = JSON.parse(readFileSync2(statePath2, "utf8"));
|
|
9150
9325
|
return value.version === 1 && value.targetPath === targetPath2 ? value : void 0;
|
|
9151
9326
|
} catch {
|
|
9152
9327
|
return void 0;
|
|
9153
9328
|
}
|
|
9154
9329
|
}
|
|
9155
9330
|
function writeState2(statePath2, state) {
|
|
9156
|
-
|
|
9157
|
-
|
|
9331
|
+
mkdirSync2(dirname4(statePath2), { recursive: true });
|
|
9332
|
+
writeFileSync2(statePath2, `${JSON.stringify(state, null, 2)}
|
|
9158
9333
|
`);
|
|
9159
9334
|
}
|
|
9160
9335
|
function originalBytes(state) {
|
|
9161
9336
|
return state.original.existed ? Buffer.from(state.original.base64 ?? "", "base64") : void 0;
|
|
9162
9337
|
}
|
|
9163
|
-
|
|
9338
|
+
function protocolStatusDshUser(_options) {
|
|
9339
|
+
return { unsupported: "dsh \u6CA1\u6709\u7528\u6237\u7EA7\u6307\u4EE4\u6587\u4EF6,\u8BF7\u6309\u9879\u76EE\u5B89\u88C5" };
|
|
9340
|
+
}
|
|
9341
|
+
var SHARED_MESSAGE, DISABLED_MESSAGE, installProtocolDshUser, uninstallProtocolDshUser;
|
|
9164
9342
|
var init_protocol = __esm({
|
|
9165
9343
|
"packages/adapter-dsh/dist/protocol.js"() {
|
|
9166
9344
|
"use strict";
|
|
@@ -9168,6 +9346,8 @@ var init_protocol = __esm({
|
|
|
9168
9346
|
init_dump_config();
|
|
9169
9347
|
SHARED_MESSAGE = "\u6B64 AGENTS.md \u534F\u8BAE\u5757\u7531 Codex \u4E0E dsh \u5171\u7528";
|
|
9170
9348
|
DISABLED_MESSAGE = "dsh \u6307\u4EE4\u52A0\u8F7D\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u89C1\u63A7\u5236\u9875\u5F00\u5173";
|
|
9349
|
+
installProtocolDshUser = protocolStatusDshUser;
|
|
9350
|
+
uninstallProtocolDshUser = protocolStatusDshUser;
|
|
9171
9351
|
}
|
|
9172
9352
|
});
|
|
9173
9353
|
|
|
@@ -9183,18 +9363,21 @@ __export(dist_exports, {
|
|
|
9183
9363
|
hasManagedHooks: () => hasManagedHooks,
|
|
9184
9364
|
installDshHooks: () => installDshHooks,
|
|
9185
9365
|
installProtocolDsh: () => installProtocolDsh,
|
|
9366
|
+
installProtocolDshUser: () => installProtocolDshUser,
|
|
9186
9367
|
parseDumpConfig: () => parseDumpConfig,
|
|
9187
9368
|
protocolStatusDsh: () => protocolStatusDsh,
|
|
9369
|
+
protocolStatusDshUser: () => protocolStatusDshUser,
|
|
9188
9370
|
resolveDshHome: () => resolveDshHome,
|
|
9189
9371
|
resolveDshHookPaths: () => resolveDshHookPaths,
|
|
9190
9372
|
retireLegacyDshHomeHooks: () => retireLegacyDshHomeHooks,
|
|
9191
9373
|
uninstallDshHooks: () => uninstallDshHooks,
|
|
9192
|
-
uninstallProtocolDsh: () => uninstallProtocolDsh
|
|
9374
|
+
uninstallProtocolDsh: () => uninstallProtocolDsh,
|
|
9375
|
+
uninstallProtocolDshUser: () => uninstallProtocolDshUser
|
|
9193
9376
|
});
|
|
9194
9377
|
import { execFile } from "node:child_process";
|
|
9195
|
-
import { existsSync as
|
|
9378
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
9196
9379
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
9197
|
-
import { join as
|
|
9380
|
+
import { join as join5 } from "node:path";
|
|
9198
9381
|
import { promisify } from "node:util";
|
|
9199
9382
|
async function execVersionViaPath() {
|
|
9200
9383
|
const { stdout } = await execFileAsync("dsh", ["-V"], {
|
|
@@ -9267,7 +9450,7 @@ function createAdapter(options = {}) {
|
|
|
9267
9450
|
// 检测与 CC/Codex 同构:探用户 dsh 家目录(homeDir/.dsh → $DSH_HOME → ~/.dsh)是否存在。
|
|
9268
9451
|
// 版本尽力:PATH 上 `dsh -V`,3 秒超时;失败不影响 installed 判定。
|
|
9269
9452
|
async detect(options2) {
|
|
9270
|
-
if (!
|
|
9453
|
+
if (!existsSync3(resolveDshHome(options2)))
|
|
9271
9454
|
return { installed: false };
|
|
9272
9455
|
const version = await loadVersion();
|
|
9273
9456
|
return version !== void 0 ? { installed: true, version } : { installed: true };
|
|
@@ -9300,7 +9483,7 @@ function createAdapter(options = {}) {
|
|
|
9300
9483
|
},
|
|
9301
9484
|
async planAction(action, options2) {
|
|
9302
9485
|
const text = await loadDumpText();
|
|
9303
|
-
const file = dumpConfigPath ??
|
|
9486
|
+
const file = dumpConfigPath ?? join5(resolveDshHookPaths(options2).dshHome, `dump-config(${profile})`);
|
|
9304
9487
|
return await planDshToggle(action, { text, file }, options2);
|
|
9305
9488
|
},
|
|
9306
9489
|
async applyAction(plan, options2) {
|
|
@@ -9331,7 +9514,7 @@ var init_dist2 = __esm({
|
|
|
9331
9514
|
|
|
9332
9515
|
// packages/adapter-cc/dist/walk.js
|
|
9333
9516
|
import { readdirSync } from "node:fs";
|
|
9334
|
-
import { join as
|
|
9517
|
+
import { join as join9, parse as parse2, resolve as resolve2 } from "node:path";
|
|
9335
9518
|
function newWalkStats(entryBudget = MAX_WALK_ENTRIES) {
|
|
9336
9519
|
return { unknownErrors: 0, truncated: false, entriesLeft: entryBudget };
|
|
9337
9520
|
}
|
|
@@ -9358,7 +9541,7 @@ function walkFiles(dir, fileName, stats = newWalkStats()) {
|
|
|
9358
9541
|
return;
|
|
9359
9542
|
}
|
|
9360
9543
|
stats.entriesLeft -= 1;
|
|
9361
|
-
const p =
|
|
9544
|
+
const p = join9(d, entry.name);
|
|
9362
9545
|
if (entry.isDirectory()) {
|
|
9363
9546
|
if (entry.name.startsWith(".") || SKIP_DIR_NAMES.has(entry.name))
|
|
9364
9547
|
continue;
|
|
@@ -9375,7 +9558,7 @@ function walkFiles(dir, fileName, stats = newWalkStats()) {
|
|
|
9375
9558
|
return found;
|
|
9376
9559
|
}
|
|
9377
9560
|
function listMdFiles(dir, stats) {
|
|
9378
|
-
return safeReaddir(dir, stats).map((e) => e.name).filter((n) => n.endsWith(".md")).sort().map((n) =>
|
|
9561
|
+
return safeReaddir(dir, stats).map((e) => e.name).filter((n) => n.endsWith(".md")).sort().map((n) => join9(dir, n));
|
|
9379
9562
|
}
|
|
9380
9563
|
function isBareProjectDir(projectDir, homeDir) {
|
|
9381
9564
|
const r = resolve2(projectDir);
|
|
@@ -9393,21 +9576,21 @@ var init_walk = __esm({
|
|
|
9393
9576
|
});
|
|
9394
9577
|
|
|
9395
9578
|
// packages/adapter-cc/dist/detect.js
|
|
9396
|
-
import { existsSync as
|
|
9579
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, statSync } from "node:fs";
|
|
9397
9580
|
import { homedir as homedir5 } from "node:os";
|
|
9398
|
-
import { join as
|
|
9581
|
+
import { join as join10 } from "node:path";
|
|
9399
9582
|
function probeVersion(homeDir, stats = newWalkStats()) {
|
|
9400
|
-
const root =
|
|
9583
|
+
const root = join10(homeDir, ".claude", "projects");
|
|
9401
9584
|
let latest;
|
|
9402
9585
|
for (const entry of safeReaddir(root, stats)) {
|
|
9403
9586
|
if (!entry.isDirectory())
|
|
9404
9587
|
continue;
|
|
9405
|
-
const dir =
|
|
9588
|
+
const dir = join10(root, entry.name);
|
|
9406
9589
|
for (const sub of safeReaddir(dir, stats)) {
|
|
9407
9590
|
const name = sub.name;
|
|
9408
9591
|
if (!name.endsWith(".jsonl"))
|
|
9409
9592
|
continue;
|
|
9410
|
-
const file =
|
|
9593
|
+
const file = join10(dir, name);
|
|
9411
9594
|
let mtimeMs;
|
|
9412
9595
|
try {
|
|
9413
9596
|
mtimeMs = statSync(file).mtimeMs;
|
|
@@ -9423,7 +9606,7 @@ function probeVersion(homeDir, stats = newWalkStats()) {
|
|
|
9423
9606
|
return void 0;
|
|
9424
9607
|
let lines2;
|
|
9425
9608
|
try {
|
|
9426
|
-
lines2 =
|
|
9609
|
+
lines2 = readFileSync5(latest.file, "utf8").split("\n");
|
|
9427
9610
|
} catch (error) {
|
|
9428
9611
|
recordWalkError(error, stats);
|
|
9429
9612
|
return void 0;
|
|
@@ -9443,7 +9626,7 @@ function probeVersion(homeDir, stats = newWalkStats()) {
|
|
|
9443
9626
|
}
|
|
9444
9627
|
async function detectCc(options) {
|
|
9445
9628
|
const homeDir = options?.homeDir ?? homedir5();
|
|
9446
|
-
const installed =
|
|
9629
|
+
const installed = existsSync5(join10(homeDir, ".claude")) || existsSync5(join10(homeDir, ".claude.json"));
|
|
9447
9630
|
if (!installed)
|
|
9448
9631
|
return { installed: false };
|
|
9449
9632
|
const version = probeVersion(homeDir);
|
|
@@ -9458,11 +9641,11 @@ var init_detect = __esm({
|
|
|
9458
9641
|
|
|
9459
9642
|
// packages/adapter-cc/dist/scan.js
|
|
9460
9643
|
import { Buffer as Buffer4 } from "node:buffer";
|
|
9461
|
-
import { existsSync as
|
|
9644
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
|
|
9462
9645
|
import { homedir as homedir6 } from "node:os";
|
|
9463
|
-
import { basename as
|
|
9646
|
+
import { basename as basename4, dirname as dirname7, join as join11, resolve as resolve3, sep } from "node:path";
|
|
9464
9647
|
function readJsonFile(file) {
|
|
9465
|
-
const text =
|
|
9648
|
+
const text = readFileSync6(file, "utf8");
|
|
9466
9649
|
try {
|
|
9467
9650
|
return JSON.parse(text);
|
|
9468
9651
|
} catch (e) {
|
|
@@ -9478,13 +9661,13 @@ function recordField(v, key) {
|
|
|
9478
9661
|
}
|
|
9479
9662
|
function readSettingsChain(homeDir, projectDir) {
|
|
9480
9663
|
const chain = [
|
|
9481
|
-
{ file:
|
|
9482
|
-
{ file:
|
|
9483
|
-
{ file:
|
|
9664
|
+
{ file: join11(homeDir, ".claude", "settings.json"), source: "user" },
|
|
9665
|
+
{ file: join11(projectDir, ".claude", "settings.json"), source: "project" },
|
|
9666
|
+
{ file: join11(projectDir, ".claude", "settings.local.json"), source: "local" }
|
|
9484
9667
|
];
|
|
9485
9668
|
const out = [];
|
|
9486
9669
|
for (const { file, source } of chain) {
|
|
9487
|
-
if (!
|
|
9670
|
+
if (!existsSync6(file))
|
|
9488
9671
|
continue;
|
|
9489
9672
|
const data = asRecord(readJsonFile(file));
|
|
9490
9673
|
if (!data)
|
|
@@ -9527,7 +9710,7 @@ function ruleItem(file, source, stats) {
|
|
|
9527
9710
|
return {
|
|
9528
9711
|
id: "",
|
|
9529
9712
|
slot: "rules",
|
|
9530
|
-
nativeName:
|
|
9713
|
+
nativeName: basename4(file),
|
|
9531
9714
|
nativePath: file,
|
|
9532
9715
|
tokens: estimateTokens(statSync2(file).size),
|
|
9533
9716
|
residency: "resident",
|
|
@@ -9547,20 +9730,20 @@ function buildRules(homeDir, projectDir, stats) {
|
|
|
9547
9730
|
if (item !== void 0)
|
|
9548
9731
|
items.push(item);
|
|
9549
9732
|
};
|
|
9550
|
-
const userClaudeMd =
|
|
9551
|
-
if (
|
|
9733
|
+
const userClaudeMd = join11(homeDir, ".claude", "CLAUDE.md");
|
|
9734
|
+
if (existsSync6(userClaudeMd))
|
|
9552
9735
|
append(userClaudeMd, "user");
|
|
9553
|
-
for (const f of listMdFiles(
|
|
9736
|
+
for (const f of listMdFiles(join11(homeDir, ".claude", "rules"), stats))
|
|
9554
9737
|
append(f, "user");
|
|
9555
9738
|
if (isBareProjectDir(projectDir, homeDir)) {
|
|
9556
|
-
const direct =
|
|
9557
|
-
if (
|
|
9739
|
+
const direct = join11(projectDir, "CLAUDE.md");
|
|
9740
|
+
if (existsSync6(direct))
|
|
9558
9741
|
append(direct, "project");
|
|
9559
9742
|
} else {
|
|
9560
9743
|
for (const f of walkFiles(projectDir, "CLAUDE.md", stats))
|
|
9561
9744
|
append(f, "project");
|
|
9562
9745
|
}
|
|
9563
|
-
for (const f of listMdFiles(
|
|
9746
|
+
for (const f of listMdFiles(join11(projectDir, ".claude", "rules"), stats)) {
|
|
9564
9747
|
append(f, "project");
|
|
9565
9748
|
}
|
|
9566
9749
|
return items;
|
|
@@ -9583,14 +9766,14 @@ function parseSkillFrontmatter(content) {
|
|
|
9583
9766
|
return out;
|
|
9584
9767
|
}
|
|
9585
9768
|
function buildSkills(homeDir, projectDir, overrides, stats) {
|
|
9586
|
-
const userRoot =
|
|
9587
|
-
const syncedRoot =
|
|
9769
|
+
const userRoot = join11(homeDir, ".claude", "skills");
|
|
9770
|
+
const syncedRoot = join11(userRoot, "synced");
|
|
9588
9771
|
const roots = [
|
|
9589
9772
|
{ root: userRoot, source: "user", exclude: syncedRoot },
|
|
9590
9773
|
// projectDir 为家目录时,项目 skills 根与 user 根是同一目录,再走一遍会把每个
|
|
9591
9774
|
// skill 重复列为 project 层;bare root 无项目上下文 → 不设项目 skills 根
|
|
9592
|
-
...isBareProjectDir(projectDir, homeDir) ? [] : [{ root:
|
|
9593
|
-
{ root:
|
|
9775
|
+
...isBareProjectDir(projectDir, homeDir) ? [] : [{ root: join11(projectDir, ".claude", "skills"), source: "project" }],
|
|
9776
|
+
{ root: join11(homeDir, ".claude", "plugins"), source: "plugin" },
|
|
9594
9777
|
{ root: syncedRoot, source: "synced" }
|
|
9595
9778
|
];
|
|
9596
9779
|
const items = [];
|
|
@@ -9599,8 +9782,8 @@ function buildSkills(homeDir, projectDir, overrides, stats) {
|
|
|
9599
9782
|
if (exclude && (skillFile === exclude || skillFile.startsWith(exclude + sep)))
|
|
9600
9783
|
continue;
|
|
9601
9784
|
try {
|
|
9602
|
-
const fm = parseSkillFrontmatter(
|
|
9603
|
-
const name = fm.name ??
|
|
9785
|
+
const fm = parseSkillFrontmatter(readFileSync6(skillFile, "utf8"));
|
|
9786
|
+
const name = fm.name ?? basename4(dirname7(skillFile));
|
|
9604
9787
|
const size = statSync2(skillFile).size;
|
|
9605
9788
|
items.push({
|
|
9606
9789
|
id: "",
|
|
@@ -9624,9 +9807,9 @@ function buildSkills(homeDir, projectDir, overrides, stats) {
|
|
|
9624
9807
|
}
|
|
9625
9808
|
function buildTools(homeDir, projectDir) {
|
|
9626
9809
|
const items = [];
|
|
9627
|
-
const claudeJsonPath =
|
|
9810
|
+
const claudeJsonPath = join11(homeDir, ".claude.json");
|
|
9628
9811
|
let claudeJson;
|
|
9629
|
-
if (
|
|
9812
|
+
if (existsSync6(claudeJsonPath))
|
|
9630
9813
|
claudeJson = asRecord(readJsonFile(claudeJsonPath));
|
|
9631
9814
|
const projectEntry = recordField(claudeJson?.projects, resolve3(projectDir));
|
|
9632
9815
|
const disabledRaw = projectEntry?.disabledMcpServers;
|
|
@@ -9650,8 +9833,8 @@ function buildTools(homeDir, projectDir) {
|
|
|
9650
9833
|
for (const name of Object.keys(localServers).sort()) {
|
|
9651
9834
|
items.push(mcpItem(name, "local", claudeJsonPath));
|
|
9652
9835
|
}
|
|
9653
|
-
const mcpJsonPath =
|
|
9654
|
-
if (
|
|
9836
|
+
const mcpJsonPath = join11(projectDir, ".mcp.json");
|
|
9837
|
+
if (existsSync6(mcpJsonPath)) {
|
|
9655
9838
|
const projectServers = recordField(readJsonFile(mcpJsonPath), "mcpServers") ?? {};
|
|
9656
9839
|
for (const name of Object.keys(projectServers).sort()) {
|
|
9657
9840
|
items.push(mcpItem(name, "project", mcpJsonPath));
|
|
@@ -9697,7 +9880,7 @@ function lastContextTotal(file, stats) {
|
|
|
9697
9880
|
let total;
|
|
9698
9881
|
let text;
|
|
9699
9882
|
try {
|
|
9700
|
-
text =
|
|
9883
|
+
text = readFileSync6(file, "utf8");
|
|
9701
9884
|
} catch (error) {
|
|
9702
9885
|
recordWalkError(error, stats);
|
|
9703
9886
|
return void 0;
|
|
@@ -9725,10 +9908,10 @@ function lastContextTotal(file, stats) {
|
|
|
9725
9908
|
return total;
|
|
9726
9909
|
}
|
|
9727
9910
|
function buildHistory(homeDir, projectDir, stats) {
|
|
9728
|
-
const dir =
|
|
9911
|
+
const dir = join11(homeDir, ".claude", "projects", projectSlug(projectDir));
|
|
9729
9912
|
const items = [];
|
|
9730
9913
|
for (const name of safeReaddir(dir, stats).map((e) => e.name).filter((n) => n.endsWith(".jsonl")).sort()) {
|
|
9731
|
-
const file =
|
|
9914
|
+
const file = join11(dir, name);
|
|
9732
9915
|
const total = lastContextTotal(file, stats);
|
|
9733
9916
|
if (total === void 0)
|
|
9734
9917
|
continue;
|
|
@@ -9839,9 +10022,9 @@ var init_scan = __esm({
|
|
|
9839
10022
|
});
|
|
9840
10023
|
|
|
9841
10024
|
// packages/adapter-cc/dist/actions.js
|
|
9842
|
-
import { existsSync as
|
|
10025
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync7, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
9843
10026
|
import { homedir as homedir7 } from "node:os";
|
|
9844
|
-
import { basename as
|
|
10027
|
+
import { basename as basename5, dirname as dirname8, join as join12, resolve as resolve4 } from "node:path";
|
|
9845
10028
|
function asRecord2(v) {
|
|
9846
10029
|
return typeof v === "object" && v !== null && !Array.isArray(v) ? v : void 0;
|
|
9847
10030
|
}
|
|
@@ -9865,10 +10048,10 @@ function deepEqual(a, b) {
|
|
|
9865
10048
|
}
|
|
9866
10049
|
function backupDirPath(homeDir) {
|
|
9867
10050
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
9868
|
-
const root =
|
|
9869
|
-
let dir =
|
|
9870
|
-
for (let n = 2;
|
|
9871
|
-
dir =
|
|
10051
|
+
const root = join12(homeDir, ".wingman", "backups");
|
|
10052
|
+
let dir = join12(root, ts);
|
|
10053
|
+
for (let n = 2; existsSync7(dir); n++)
|
|
10054
|
+
dir = join12(root, `${ts}-${n}`);
|
|
9872
10055
|
return dir;
|
|
9873
10056
|
}
|
|
9874
10057
|
function decodeUtf8Strict3(buffer, file) {
|
|
@@ -9880,15 +10063,15 @@ function decodeUtf8Strict3(buffer, file) {
|
|
|
9880
10063
|
}
|
|
9881
10064
|
function readSettingsSnapshots(homeDir, projectDir) {
|
|
9882
10065
|
const files = [
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
10066
|
+
join12(homeDir, ".claude", "settings.json"),
|
|
10067
|
+
join12(projectDir, ".claude", "settings.json"),
|
|
10068
|
+
join12(projectDir, ".claude", "settings.local.json")
|
|
9886
10069
|
];
|
|
9887
10070
|
const out = [];
|
|
9888
10071
|
for (const file of files) {
|
|
9889
|
-
if (!
|
|
10072
|
+
if (!existsSync7(file))
|
|
9890
10073
|
continue;
|
|
9891
|
-
const raw = decodeUtf8Strict3(
|
|
10074
|
+
const raw = decodeUtf8Strict3(readFileSync7(file), file);
|
|
9892
10075
|
let parsed;
|
|
9893
10076
|
try {
|
|
9894
10077
|
parsed = JSON.parse(raw);
|
|
@@ -9911,7 +10094,7 @@ function overridesRecord(s) {
|
|
|
9911
10094
|
return rec;
|
|
9912
10095
|
}
|
|
9913
10096
|
function skillTargetFile(item, homeDir, projectDir) {
|
|
9914
|
-
return item.source === "project" ?
|
|
10097
|
+
return item.source === "project" ? join12(projectDir, ".claude", "settings.json") : join12(homeDir, ".claude", "settings.json");
|
|
9915
10098
|
}
|
|
9916
10099
|
function planSkillToggle(item, enable, homeDir, projectDir) {
|
|
9917
10100
|
const name = item.nativeName;
|
|
@@ -9964,11 +10147,11 @@ function planSkillToggle(item, enable, homeDir, projectDir) {
|
|
|
9964
10147
|
});
|
|
9965
10148
|
}
|
|
9966
10149
|
function planMcpToggle(name, enable, homeDir, projectDir) {
|
|
9967
|
-
const file =
|
|
9968
|
-
if (!
|
|
10150
|
+
const file = join12(homeDir, ".claude.json");
|
|
10151
|
+
if (!existsSync7(file)) {
|
|
9969
10152
|
throw new Error(`\u62D2\u7EDD:\u627E\u4E0D\u5230 ${file}(MCP \u8FDE\u63A5\u5F00\u5173\u6309\u9879\u76EE\u5B58\u653E\u4E8E\u8BE5\u6587\u4EF6)`);
|
|
9970
10153
|
}
|
|
9971
|
-
const raw =
|
|
10154
|
+
const raw = readFileSync7(file, "utf8");
|
|
9972
10155
|
let parsed;
|
|
9973
10156
|
try {
|
|
9974
10157
|
parsed = JSON.parse(raw);
|
|
@@ -10042,24 +10225,24 @@ function collectRefSources(homeDir, projectDir, exclude) {
|
|
|
10042
10225
|
sources.push({ file, text });
|
|
10043
10226
|
};
|
|
10044
10227
|
const pushFile = (file) => {
|
|
10045
|
-
if (!seen.has(file) &&
|
|
10046
|
-
push(file,
|
|
10228
|
+
if (!seen.has(file) && existsSync7(file))
|
|
10229
|
+
push(file, readFileSync7(file, "utf8"));
|
|
10047
10230
|
};
|
|
10048
10231
|
const bareRoot = isBareProjectDir(projectDir, homeDir);
|
|
10049
|
-
pushFile(
|
|
10050
|
-
for (const f of listMdFiles(
|
|
10232
|
+
pushFile(join12(homeDir, ".claude", "CLAUDE.md"));
|
|
10233
|
+
for (const f of listMdFiles(join12(homeDir, ".claude", "rules")))
|
|
10051
10234
|
pushFile(f);
|
|
10052
10235
|
if (bareRoot)
|
|
10053
|
-
pushFile(
|
|
10236
|
+
pushFile(join12(projectDir, "CLAUDE.md"));
|
|
10054
10237
|
else
|
|
10055
10238
|
for (const f of walkFiles(projectDir, "CLAUDE.md"))
|
|
10056
10239
|
pushFile(f);
|
|
10057
|
-
for (const f of listMdFiles(
|
|
10240
|
+
for (const f of listMdFiles(join12(projectDir, ".claude", "rules")))
|
|
10058
10241
|
pushFile(f);
|
|
10059
10242
|
const skillRoots = [
|
|
10060
|
-
|
|
10061
|
-
...bareRoot ? [] : [
|
|
10062
|
-
|
|
10243
|
+
join12(homeDir, ".claude", "skills"),
|
|
10244
|
+
...bareRoot ? [] : [join12(projectDir, ".claude", "skills")],
|
|
10245
|
+
join12(homeDir, ".claude", "plugins")
|
|
10063
10246
|
];
|
|
10064
10247
|
for (const root of skillRoots) {
|
|
10065
10248
|
for (const f of walkFiles(root, "SKILL.md")) {
|
|
@@ -10068,20 +10251,20 @@ function collectRefSources(homeDir, projectDir, exclude) {
|
|
|
10068
10251
|
}
|
|
10069
10252
|
}
|
|
10070
10253
|
for (const dir of [
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
|
|
10254
|
+
join12(homeDir, ".claude", "agents"),
|
|
10255
|
+
join12(projectDir, ".claude", "agents"),
|
|
10256
|
+
join12(homeDir, ".claude", "commands"),
|
|
10257
|
+
join12(projectDir, ".claude", "commands")
|
|
10075
10258
|
]) {
|
|
10076
10259
|
for (const f of listMdFiles(dir))
|
|
10077
10260
|
pushFile(f);
|
|
10078
10261
|
}
|
|
10079
10262
|
for (const s of readSettingsSnapshots(homeDir, projectDir))
|
|
10080
10263
|
push(s.file, s.raw);
|
|
10081
|
-
for (const file of [
|
|
10082
|
-
if (seen.has(file) || !
|
|
10264
|
+
for (const file of [join12(projectDir, ".mcp.json"), join12(homeDir, ".claude.json")]) {
|
|
10265
|
+
if (seen.has(file) || !existsSync7(file))
|
|
10083
10266
|
continue;
|
|
10084
|
-
const raw =
|
|
10267
|
+
const raw = readFileSync7(file, "utf8");
|
|
10085
10268
|
let parsed;
|
|
10086
10269
|
try {
|
|
10087
10270
|
parsed = JSON.parse(raw);
|
|
@@ -10188,14 +10371,14 @@ async function applyActionCc(plan, _options) {
|
|
|
10188
10371
|
const currentByFile = /* @__PURE__ */ new Map();
|
|
10189
10372
|
for (const w of plan.writes) {
|
|
10190
10373
|
if (w.kind === "create") {
|
|
10191
|
-
if (
|
|
10374
|
+
if (existsSync7(w.file)) {
|
|
10192
10375
|
return { ok: false, error: `\u62D2\u7EDD\u6267\u884C:${w.file} \u5728 plan \u540E\u88AB\u521B\u5EFA,\u8BF7\u91CD\u65B0 plan` };
|
|
10193
10376
|
}
|
|
10194
10377
|
} else {
|
|
10195
|
-
if (!
|
|
10378
|
+
if (!existsSync7(w.file)) {
|
|
10196
10379
|
return { ok: false, error: `\u62D2\u7EDD\u6267\u884C:${w.file} \u5DF2\u4E0D\u5B58\u5728(plan \u540E\u88AB\u6539\u52A8),\u8BF7\u91CD\u65B0 plan` };
|
|
10197
10380
|
}
|
|
10198
|
-
const currentRaw =
|
|
10381
|
+
const currentRaw = readFileSync7(w.file);
|
|
10199
10382
|
if (!currentRaw.equals(Buffer.from(w.before, "utf8"))) {
|
|
10200
10383
|
return { ok: false, error: `\u62D2\u7EDD\u6267\u884C:${w.file} \u5728 plan \u540E\u88AB\u6539\u8FC7,\u8BF7\u91CD\u65B0 plan` };
|
|
10201
10384
|
}
|
|
@@ -10203,15 +10386,15 @@ async function applyActionCc(plan, _options) {
|
|
|
10203
10386
|
}
|
|
10204
10387
|
}
|
|
10205
10388
|
const toBackup = plan.writes.filter((w) => w.kind !== "create");
|
|
10206
|
-
|
|
10389
|
+
mkdirSync4(plan.backupDir, { recursive: true });
|
|
10207
10390
|
const manifestFiles = toBackup.map((w, i) => ({
|
|
10208
|
-
backup: `${i}-${
|
|
10391
|
+
backup: `${i}-${basename5(w.file)}`,
|
|
10209
10392
|
target: w.file
|
|
10210
10393
|
}));
|
|
10211
10394
|
toBackup.forEach((w, i) => {
|
|
10212
|
-
|
|
10395
|
+
writeFileSync5(join12(plan.backupDir, `${i}-${basename5(w.file)}`), currentByFile.get(w.file));
|
|
10213
10396
|
});
|
|
10214
|
-
|
|
10397
|
+
writeFileSync5(join12(plan.backupDir, "manifest.json"), serialize({
|
|
10215
10398
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10216
10399
|
harness: "cc",
|
|
10217
10400
|
action: plan.action,
|
|
@@ -10221,10 +10404,10 @@ async function applyActionCc(plan, _options) {
|
|
|
10221
10404
|
try {
|
|
10222
10405
|
for (const w of plan.writes) {
|
|
10223
10406
|
if (w.kind === "delete") {
|
|
10224
|
-
|
|
10407
|
+
rmSync3(w.file);
|
|
10225
10408
|
} else {
|
|
10226
|
-
|
|
10227
|
-
|
|
10409
|
+
mkdirSync4(dirname8(w.file), { recursive: true });
|
|
10410
|
+
writeFileSync5(w.file, w.after ?? "");
|
|
10228
10411
|
}
|
|
10229
10412
|
written.push(w);
|
|
10230
10413
|
}
|
|
@@ -10233,9 +10416,9 @@ async function applyActionCc(plan, _options) {
|
|
|
10233
10416
|
for (const w of written) {
|
|
10234
10417
|
try {
|
|
10235
10418
|
if (w.kind === "create")
|
|
10236
|
-
|
|
10419
|
+
rmSync3(w.file, { force: true });
|
|
10237
10420
|
else
|
|
10238
|
-
|
|
10421
|
+
writeFileSync5(w.file, w.before ?? "");
|
|
10239
10422
|
} catch {
|
|
10240
10423
|
failures.push(w.file);
|
|
10241
10424
|
}
|
|
@@ -10244,12 +10427,12 @@ async function applyActionCc(plan, _options) {
|
|
|
10244
10427
|
return { ok: false, error: `\u5199\u5165\u5931\u8D25:${e.message};${rollbackNote}` };
|
|
10245
10428
|
}
|
|
10246
10429
|
for (const w of plan.writes) {
|
|
10247
|
-
if (
|
|
10430
|
+
if (basename5(w.file) !== ".claude.json" || w.kind !== "modify" || w.after === void 0) {
|
|
10248
10431
|
continue;
|
|
10249
10432
|
}
|
|
10250
10433
|
let verified = false;
|
|
10251
10434
|
try {
|
|
10252
|
-
verified = deepEqual(JSON.parse(
|
|
10435
|
+
verified = deepEqual(JSON.parse(readFileSync7(w.file, "utf8")), JSON.parse(w.after));
|
|
10253
10436
|
} catch {
|
|
10254
10437
|
verified = false;
|
|
10255
10438
|
}
|
|
@@ -10275,9 +10458,9 @@ var init_actions = __esm({
|
|
|
10275
10458
|
});
|
|
10276
10459
|
|
|
10277
10460
|
// packages/adapter-cc/dist/hooks.js
|
|
10278
|
-
import { existsSync as
|
|
10461
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync8, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
10279
10462
|
import { homedir as homedir8 } from "node:os";
|
|
10280
|
-
import { dirname as
|
|
10463
|
+
import { dirname as dirname9, join as join13 } from "node:path";
|
|
10281
10464
|
function wingmanUrl(port) {
|
|
10282
10465
|
return `http://127.0.0.1:${port}${SIGNATURE}`;
|
|
10283
10466
|
}
|
|
@@ -10289,18 +10472,18 @@ function isWingmanHandler(h) {
|
|
|
10289
10472
|
return rec?.type === "http" && typeof rec.url === "string" && rec.url.includes(SIGNATURE);
|
|
10290
10473
|
}
|
|
10291
10474
|
function wingmanRoot(homeDir) {
|
|
10292
|
-
return
|
|
10475
|
+
return join13(homeDir, ".wingman");
|
|
10293
10476
|
}
|
|
10294
10477
|
function statePath(homeDir) {
|
|
10295
|
-
return
|
|
10478
|
+
return join13(wingmanRoot(homeDir), "state", "cc-hooks.json");
|
|
10296
10479
|
}
|
|
10297
10480
|
function readState3(homeDir) {
|
|
10298
10481
|
const file = statePath(homeDir);
|
|
10299
|
-
if (!
|
|
10482
|
+
if (!existsSync8(file))
|
|
10300
10483
|
return void 0;
|
|
10301
10484
|
let parsed;
|
|
10302
10485
|
try {
|
|
10303
|
-
parsed = JSON.parse(
|
|
10486
|
+
parsed = JSON.parse(readFileSync8(file, "utf8"));
|
|
10304
10487
|
} catch {
|
|
10305
10488
|
return void 0;
|
|
10306
10489
|
}
|
|
@@ -10321,23 +10504,23 @@ function readState3(homeDir) {
|
|
|
10321
10504
|
}
|
|
10322
10505
|
function writeState3(homeDir, state) {
|
|
10323
10506
|
const file = statePath(homeDir);
|
|
10324
|
-
|
|
10325
|
-
|
|
10507
|
+
mkdirSync5(dirname9(file), { recursive: true });
|
|
10508
|
+
writeFileSync6(file, `${JSON.stringify(state, null, 2)}
|
|
10326
10509
|
`);
|
|
10327
10510
|
}
|
|
10328
10511
|
function makeBackupDir(homeDir) {
|
|
10329
10512
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
10330
|
-
const root =
|
|
10331
|
-
let dir =
|
|
10332
|
-
for (let n = 2;
|
|
10333
|
-
dir =
|
|
10334
|
-
|
|
10513
|
+
const root = join13(wingmanRoot(homeDir), "backups");
|
|
10514
|
+
let dir = join13(root, ts);
|
|
10515
|
+
for (let n = 2; existsSync8(dir); n++)
|
|
10516
|
+
dir = join13(root, `${ts}-${n}`);
|
|
10517
|
+
mkdirSync5(dir, { recursive: true });
|
|
10335
10518
|
return dir;
|
|
10336
10519
|
}
|
|
10337
|
-
function
|
|
10338
|
-
if (!
|
|
10520
|
+
function readTarget2(target) {
|
|
10521
|
+
if (!existsSync8(target))
|
|
10339
10522
|
return { bytes: null, settings: {} };
|
|
10340
|
-
const bytes =
|
|
10523
|
+
const bytes = readFileSync8(target, "utf8");
|
|
10341
10524
|
let parsed;
|
|
10342
10525
|
try {
|
|
10343
10526
|
parsed = JSON.parse(bytes);
|
|
@@ -10440,13 +10623,13 @@ function deepEqual2(a, b) {
|
|
|
10440
10623
|
return false;
|
|
10441
10624
|
}
|
|
10442
10625
|
function targetPath(homeDir) {
|
|
10443
|
-
return
|
|
10626
|
+
return join13(homeDir, ".claude", "settings.json");
|
|
10444
10627
|
}
|
|
10445
10628
|
async function installHooksCc(port, options) {
|
|
10446
10629
|
const homeDir = options?.homeDir ?? homedir8();
|
|
10447
10630
|
const target = targetPath(homeDir);
|
|
10448
10631
|
const url = wingmanUrl(port);
|
|
10449
|
-
const { bytes, settings } =
|
|
10632
|
+
const { bytes, settings } = readTarget2(target);
|
|
10450
10633
|
if (isFullyWired(settings, url))
|
|
10451
10634
|
return;
|
|
10452
10635
|
if (settings.hooks !== void 0 && !asRecord3(settings.hooks)) {
|
|
@@ -10462,7 +10645,7 @@ async function installHooksCc(port, options) {
|
|
|
10462
10645
|
}
|
|
10463
10646
|
const backupDir = makeBackupDir(homeDir);
|
|
10464
10647
|
if (bytes !== null)
|
|
10465
|
-
|
|
10648
|
+
writeFileSync6(join13(backupDir, "settings.json"), bytes);
|
|
10466
10649
|
const prev = readState3(homeDir);
|
|
10467
10650
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10468
10651
|
writeState3(homeDir, prev ? { ...prev, port, installedAt: now } : { target, original: bytes, backupDir, port, installedAt: now });
|
|
@@ -10474,44 +10657,44 @@ async function installHooksCc(port, options) {
|
|
|
10474
10657
|
groups.push({ hooks: [{ type: "http", url }] });
|
|
10475
10658
|
hooks[event] = groups;
|
|
10476
10659
|
}
|
|
10477
|
-
|
|
10478
|
-
|
|
10660
|
+
mkdirSync5(dirname9(target), { recursive: true });
|
|
10661
|
+
writeFileSync6(target, `${JSON.stringify(settings, null, 2)}
|
|
10479
10662
|
`);
|
|
10480
10663
|
}
|
|
10481
10664
|
async function uninstallHooksCc(options) {
|
|
10482
10665
|
const homeDir = options?.homeDir ?? homedir8();
|
|
10483
10666
|
const target = targetPath(homeDir);
|
|
10484
10667
|
const state = readState3(homeDir);
|
|
10485
|
-
if (!
|
|
10486
|
-
|
|
10668
|
+
if (!existsSync8(target)) {
|
|
10669
|
+
rmSync4(statePath(homeDir), { force: true });
|
|
10487
10670
|
return;
|
|
10488
10671
|
}
|
|
10489
|
-
const { bytes, settings } =
|
|
10672
|
+
const { bytes, settings } = readTarget2(target);
|
|
10490
10673
|
const changed = removeWingmanEntries(settings);
|
|
10491
10674
|
if (!changed) {
|
|
10492
|
-
|
|
10675
|
+
rmSync4(statePath(homeDir), { force: true });
|
|
10493
10676
|
return;
|
|
10494
10677
|
}
|
|
10495
10678
|
const backupDir = makeBackupDir(homeDir);
|
|
10496
10679
|
if (bytes !== null)
|
|
10497
|
-
|
|
10680
|
+
writeFileSync6(join13(backupDir, "settings.json"), bytes);
|
|
10498
10681
|
if (state && state.original !== null) {
|
|
10499
10682
|
const originalParsed = asRecord3(JSON.parse(state.original));
|
|
10500
10683
|
if (originalParsed && deepEqual2(normalizeForCompare(settings), normalizeForCompare(originalParsed))) {
|
|
10501
|
-
|
|
10502
|
-
|
|
10684
|
+
writeFileSync6(target, state.original);
|
|
10685
|
+
rmSync4(statePath(homeDir), { force: true });
|
|
10503
10686
|
return;
|
|
10504
10687
|
}
|
|
10505
10688
|
} else if (state && state.original === null) {
|
|
10506
10689
|
if (deepEqual2(normalizeForCompare(settings), {})) {
|
|
10507
|
-
|
|
10508
|
-
|
|
10690
|
+
rmSync4(target, { force: true });
|
|
10691
|
+
rmSync4(statePath(homeDir), { force: true });
|
|
10509
10692
|
return;
|
|
10510
10693
|
}
|
|
10511
10694
|
}
|
|
10512
|
-
|
|
10695
|
+
writeFileSync6(target, `${JSON.stringify(settings, null, 2)}
|
|
10513
10696
|
`);
|
|
10514
|
-
|
|
10697
|
+
rmSync4(statePath(homeDir), { force: true });
|
|
10515
10698
|
}
|
|
10516
10699
|
var WIRED_EVENTS, SIGNATURE;
|
|
10517
10700
|
var init_hooks2 = __esm({
|
|
@@ -10532,60 +10715,60 @@ var init_hooks2 = __esm({
|
|
|
10532
10715
|
});
|
|
10533
10716
|
|
|
10534
10717
|
// packages/adapter-cc/dist/protocol.js
|
|
10535
|
-
import { existsSync as
|
|
10718
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readdirSync as readdirSync2, readFileSync as readFileSync9, rmdirSync, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
10536
10719
|
import { homedir as homedir9 } from "node:os";
|
|
10537
|
-
import { basename as
|
|
10720
|
+
import { basename as basename6, dirname as dirname10, join as join14, resolve as resolve5 } from "node:path";
|
|
10538
10721
|
function protocolStatusCc(options) {
|
|
10539
|
-
const
|
|
10540
|
-
if (!
|
|
10541
|
-
return { harness: "cc", state: "not_installed", targetPath:
|
|
10722
|
+
const paths3 = resolveOptions2(options);
|
|
10723
|
+
if (!existsSync9(paths3.targetPath)) {
|
|
10724
|
+
return { harness: "cc", state: "not_installed", targetPath: paths3.targetPath };
|
|
10542
10725
|
}
|
|
10543
10726
|
try {
|
|
10544
|
-
return statusFromIdentity(
|
|
10727
|
+
return statusFromIdentity(paths3.targetPath, inspectPlanProtocolFile(readFileSync9(paths3.targetPath), paths3.targetPath));
|
|
10545
10728
|
} catch (error) {
|
|
10546
10729
|
return {
|
|
10547
10730
|
harness: "cc",
|
|
10548
10731
|
state: "invalid",
|
|
10549
|
-
targetPath:
|
|
10732
|
+
targetPath: paths3.targetPath,
|
|
10550
10733
|
reason: error.message
|
|
10551
10734
|
};
|
|
10552
10735
|
}
|
|
10553
10736
|
}
|
|
10554
10737
|
function installProtocolCc(options) {
|
|
10555
|
-
const
|
|
10556
|
-
const existing = readExisting(
|
|
10738
|
+
const paths3 = resolveOptions2(options);
|
|
10739
|
+
const existing = readExisting(paths3.targetPath);
|
|
10557
10740
|
const previousState = stateForIdentity2(existing?.identity);
|
|
10558
10741
|
if (previousState === "installed") {
|
|
10559
|
-
return
|
|
10742
|
+
return result3(paths3.targetPath, "install", false, previousState, existing?.text ?? "", true);
|
|
10560
10743
|
}
|
|
10561
10744
|
if (previousState === "modified")
|
|
10562
|
-
throw modifiedError2(
|
|
10745
|
+
throw modifiedError2(paths3.targetPath, "\u5B89\u88C5");
|
|
10563
10746
|
const before = existing?.text ?? "";
|
|
10564
|
-
const backupDir =
|
|
10747
|
+
const backupDir = nextBackupDir3(paths3.homeDir);
|
|
10565
10748
|
const installedSha256 = sha256Hex(PLAN_PROTOCOL_TEXT);
|
|
10566
|
-
if (!
|
|
10567
|
-
const claudeDir =
|
|
10568
|
-
const rulesDir =
|
|
10569
|
-
const prior = readState4(
|
|
10570
|
-
|
|
10571
|
-
writeState4(
|
|
10749
|
+
if (!paths3.dryRun) {
|
|
10750
|
+
const claudeDir = join14(paths3.projectDir, ".claude");
|
|
10751
|
+
const rulesDir = dirname10(paths3.targetPath);
|
|
10752
|
+
const prior = readState4(paths3.statePath);
|
|
10753
|
+
backupTarget3(backupDir, paths3.targetPath, existing?.bytes);
|
|
10754
|
+
writeState4(paths3.statePath, {
|
|
10572
10755
|
version: 1,
|
|
10573
10756
|
harness: "cc",
|
|
10574
|
-
projectDir:
|
|
10575
|
-
targetPath:
|
|
10757
|
+
projectDir: paths3.projectDir,
|
|
10758
|
+
targetPath: paths3.targetPath,
|
|
10576
10759
|
protocolVersion: PLAN_PROTOCOL_VERSION,
|
|
10577
10760
|
installedSha256,
|
|
10578
10761
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10579
10762
|
backupDir,
|
|
10580
10763
|
original: prior?.original ?? (existing === void 0 ? { existed: false } : { existed: true, base64: existing.bytes.toString("base64") }),
|
|
10581
|
-
createdClaudeDir: prior?.createdClaudeDir ?? !
|
|
10582
|
-
createdRulesDir: prior?.createdRulesDir ?? !
|
|
10764
|
+
createdClaudeDir: prior?.createdClaudeDir ?? !existsSync9(claudeDir),
|
|
10765
|
+
createdRulesDir: prior?.createdRulesDir ?? !existsSync9(rulesDir)
|
|
10583
10766
|
});
|
|
10584
|
-
|
|
10585
|
-
|
|
10767
|
+
mkdirSync6(rulesDir, { recursive: true });
|
|
10768
|
+
writeFileSync7(paths3.targetPath, PLAN_PROTOCOL_TEXT);
|
|
10586
10769
|
}
|
|
10587
10770
|
return {
|
|
10588
|
-
...
|
|
10771
|
+
...result3(paths3.targetPath, "install", true, previousState, before, true),
|
|
10589
10772
|
state: "installed",
|
|
10590
10773
|
version: PLAN_PROTOCOL_VERSION,
|
|
10591
10774
|
sha256: installedSha256,
|
|
@@ -10595,31 +10778,31 @@ function installProtocolCc(options) {
|
|
|
10595
10778
|
};
|
|
10596
10779
|
}
|
|
10597
10780
|
function uninstallProtocolCc(options) {
|
|
10598
|
-
const
|
|
10599
|
-
const existing = readExisting(
|
|
10781
|
+
const paths3 = resolveOptions2(options);
|
|
10782
|
+
const existing = readExisting(paths3.targetPath);
|
|
10600
10783
|
if (existing === void 0) {
|
|
10601
|
-
return
|
|
10784
|
+
return result3(paths3.targetPath, "uninstall", false, "not_installed", "", false);
|
|
10602
10785
|
}
|
|
10603
10786
|
const previousState = stateForIdentity2(existing.identity);
|
|
10604
10787
|
if (previousState === "modified")
|
|
10605
|
-
throw modifiedError2(
|
|
10606
|
-
const state = readState4(
|
|
10788
|
+
throw modifiedError2(paths3.targetPath, "\u5378\u8F7D");
|
|
10789
|
+
const state = readState4(paths3.statePath);
|
|
10607
10790
|
const restored = restoredOriginal(state);
|
|
10608
10791
|
const after = restored?.toString("utf8") ?? "";
|
|
10609
10792
|
const afterExists = restored !== void 0;
|
|
10610
|
-
const backupDir =
|
|
10611
|
-
if (!
|
|
10612
|
-
|
|
10793
|
+
const backupDir = nextBackupDir3(paths3.homeDir);
|
|
10794
|
+
if (!paths3.dryRun) {
|
|
10795
|
+
backupTarget3(backupDir, paths3.targetPath, existing.bytes);
|
|
10613
10796
|
if (restored === void 0)
|
|
10614
|
-
|
|
10797
|
+
rmSync5(paths3.targetPath, { force: true });
|
|
10615
10798
|
else
|
|
10616
|
-
|
|
10799
|
+
writeFileSync7(paths3.targetPath, restored);
|
|
10617
10800
|
if (restored === void 0)
|
|
10618
|
-
removeCreatedEmptyDirs(
|
|
10619
|
-
|
|
10801
|
+
removeCreatedEmptyDirs(paths3, state);
|
|
10802
|
+
rmSync5(paths3.statePath, { force: true });
|
|
10620
10803
|
}
|
|
10621
10804
|
return {
|
|
10622
|
-
...
|
|
10805
|
+
...result3(paths3.targetPath, "uninstall", true, previousState, existing.text, afterExists),
|
|
10623
10806
|
state: "not_installed",
|
|
10624
10807
|
after,
|
|
10625
10808
|
backupDir,
|
|
@@ -10629,20 +10812,20 @@ function uninstallProtocolCc(options) {
|
|
|
10629
10812
|
function resolveOptions2(options) {
|
|
10630
10813
|
const homeDir = resolve5(options?.homeDir ?? homedir9());
|
|
10631
10814
|
const projectDir = resolve5(options?.projectDir ?? process.cwd());
|
|
10632
|
-
const targetPath2 =
|
|
10815
|
+
const targetPath2 = join14(projectDir, ".claude", "rules", "wingman-plan-protocol.md");
|
|
10633
10816
|
const projectHash = sha256Hex(projectDir);
|
|
10634
10817
|
return {
|
|
10635
10818
|
homeDir,
|
|
10636
10819
|
projectDir,
|
|
10637
10820
|
dryRun: options?.dryRun ?? false,
|
|
10638
10821
|
targetPath: targetPath2,
|
|
10639
|
-
statePath:
|
|
10822
|
+
statePath: join14(homeDir, ".wingman", "state", `plan-protocol-cc-${projectHash}.json`)
|
|
10640
10823
|
};
|
|
10641
10824
|
}
|
|
10642
10825
|
function readExisting(targetPath2) {
|
|
10643
|
-
if (!
|
|
10826
|
+
if (!existsSync9(targetPath2))
|
|
10644
10827
|
return void 0;
|
|
10645
|
-
const bytes =
|
|
10828
|
+
const bytes = readFileSync9(targetPath2);
|
|
10646
10829
|
const identity = inspectPlanProtocolFile(bytes, targetPath2);
|
|
10647
10830
|
return { bytes, text: bytes.toString("utf8"), identity };
|
|
10648
10831
|
}
|
|
@@ -10665,7 +10848,7 @@ function statusFromIdentity(targetPath2, identity) {
|
|
|
10665
10848
|
...identity.kind === "modified" ? { reason: "\u53D7\u7BA1\u534F\u8BAE\u6587\u4EF6\u5DF2\u88AB\u4FEE\u6539" } : {}
|
|
10666
10849
|
};
|
|
10667
10850
|
}
|
|
10668
|
-
function
|
|
10851
|
+
function result3(targetPath2, operation, changed, previousState, before, afterExists) {
|
|
10669
10852
|
return {
|
|
10670
10853
|
harness: "cc",
|
|
10671
10854
|
operation,
|
|
@@ -10683,32 +10866,32 @@ function result2(targetPath2, operation, changed, previousState, before, afterEx
|
|
|
10683
10866
|
function modifiedError2(targetPath2, operation) {
|
|
10684
10867
|
return new Error(`\u53D7\u7BA1\u534F\u8BAE\u6587\u4EF6\u5DF2\u88AB\u4FEE\u6539(${targetPath2})\uFF0C\u62D2\u7EDD${operation}\u5E76\u4FDD\u7559\u7528\u6237\u5185\u5BB9`);
|
|
10685
10868
|
}
|
|
10686
|
-
function
|
|
10869
|
+
function nextBackupDir3(homeDir) {
|
|
10687
10870
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
10688
|
-
const root =
|
|
10689
|
-
let dir =
|
|
10690
|
-
for (let n = 2;
|
|
10691
|
-
dir =
|
|
10871
|
+
const root = join14(homeDir, ".wingman", "backups");
|
|
10872
|
+
let dir = join14(root, stamp);
|
|
10873
|
+
for (let n = 2; existsSync9(dir); n += 1)
|
|
10874
|
+
dir = join14(root, `${stamp}-${n}`);
|
|
10692
10875
|
return dir;
|
|
10693
10876
|
}
|
|
10694
|
-
function
|
|
10695
|
-
|
|
10877
|
+
function backupTarget3(backupDir, targetPath2, bytes) {
|
|
10878
|
+
mkdirSync6(backupDir, { recursive: true });
|
|
10696
10879
|
if (bytes !== void 0)
|
|
10697
|
-
|
|
10880
|
+
writeFileSync7(join14(backupDir, basename6(targetPath2)), bytes);
|
|
10698
10881
|
}
|
|
10699
10882
|
function readState4(statePath2) {
|
|
10700
|
-
if (!
|
|
10883
|
+
if (!existsSync9(statePath2))
|
|
10701
10884
|
return void 0;
|
|
10702
10885
|
try {
|
|
10703
|
-
const state = JSON.parse(
|
|
10886
|
+
const state = JSON.parse(readFileSync9(statePath2, "utf8"));
|
|
10704
10887
|
return state.version === 1 && state.harness === "cc" && typeof state.targetPath === "string" ? state : void 0;
|
|
10705
10888
|
} catch {
|
|
10706
10889
|
return void 0;
|
|
10707
10890
|
}
|
|
10708
10891
|
}
|
|
10709
10892
|
function writeState4(statePath2, state) {
|
|
10710
|
-
|
|
10711
|
-
|
|
10893
|
+
mkdirSync6(dirname10(statePath2), { recursive: true });
|
|
10894
|
+
writeFileSync7(statePath2, `${JSON.stringify(state, null, 2)}
|
|
10712
10895
|
`);
|
|
10713
10896
|
}
|
|
10714
10897
|
function restoredOriginal(state) {
|
|
@@ -10716,13 +10899,13 @@ function restoredOriginal(state) {
|
|
|
10716
10899
|
return void 0;
|
|
10717
10900
|
return Buffer.from(state.original.base64 ?? "", "base64");
|
|
10718
10901
|
}
|
|
10719
|
-
function removeCreatedEmptyDirs(
|
|
10720
|
-
const rulesDir =
|
|
10721
|
-
const claudeDir =
|
|
10722
|
-
if (state?.createdRulesDir &&
|
|
10902
|
+
function removeCreatedEmptyDirs(paths3, state) {
|
|
10903
|
+
const rulesDir = dirname10(paths3.targetPath);
|
|
10904
|
+
const claudeDir = dirname10(rulesDir);
|
|
10905
|
+
if (state?.createdRulesDir && existsSync9(rulesDir) && readdirSync2(rulesDir).length === 0) {
|
|
10723
10906
|
rmdirSync(rulesDir);
|
|
10724
10907
|
}
|
|
10725
|
-
if (state?.createdClaudeDir &&
|
|
10908
|
+
if (state?.createdClaudeDir && existsSync9(claudeDir) && readdirSync2(claudeDir).length === 0) {
|
|
10726
10909
|
rmdirSync(claudeDir);
|
|
10727
10910
|
}
|
|
10728
10911
|
}
|
|
@@ -10733,6 +10916,33 @@ var init_protocol2 = __esm({
|
|
|
10733
10916
|
}
|
|
10734
10917
|
});
|
|
10735
10918
|
|
|
10919
|
+
// packages/adapter-cc/dist/protocol-user.js
|
|
10920
|
+
import { homedir as homedir10 } from "node:os";
|
|
10921
|
+
import { join as join15, resolve as resolve6 } from "node:path";
|
|
10922
|
+
function paths(options) {
|
|
10923
|
+
const homeDir = resolve6(options?.homeDir ?? homedir10());
|
|
10924
|
+
return {
|
|
10925
|
+
homeDir,
|
|
10926
|
+
targetPath: join15(homeDir, ".claude", "CLAUDE.md"),
|
|
10927
|
+
dryRun: options?.dryRun ?? false
|
|
10928
|
+
};
|
|
10929
|
+
}
|
|
10930
|
+
function protocolStatusCcUser(options) {
|
|
10931
|
+
return { harness: "cc", ...statusPlanProtocolUser(paths(options).targetPath) };
|
|
10932
|
+
}
|
|
10933
|
+
function installProtocolCcUser(options) {
|
|
10934
|
+
return { harness: "cc", ...installPlanProtocolUser(paths(options)) };
|
|
10935
|
+
}
|
|
10936
|
+
function uninstallProtocolCcUser(options) {
|
|
10937
|
+
return { harness: "cc", ...uninstallPlanProtocolUser(paths(options)) };
|
|
10938
|
+
}
|
|
10939
|
+
var init_protocol_user = __esm({
|
|
10940
|
+
"packages/adapter-cc/dist/protocol-user.js"() {
|
|
10941
|
+
"use strict";
|
|
10942
|
+
init_dist();
|
|
10943
|
+
}
|
|
10944
|
+
});
|
|
10945
|
+
|
|
10736
10946
|
// packages/adapter-cc/dist/index.js
|
|
10737
10947
|
var dist_exports2 = {};
|
|
10738
10948
|
__export(dist_exports2, {
|
|
@@ -10740,8 +10950,11 @@ __export(dist_exports2, {
|
|
|
10740
10950
|
createAdapter: () => createAdapter2,
|
|
10741
10951
|
feedbackSignals: () => feedbackSignalsCc,
|
|
10742
10952
|
installProtocolCc: () => installProtocolCc,
|
|
10953
|
+
installProtocolCcUser: () => installProtocolCcUser,
|
|
10743
10954
|
protocolStatusCc: () => protocolStatusCc,
|
|
10744
|
-
|
|
10955
|
+
protocolStatusCcUser: () => protocolStatusCcUser,
|
|
10956
|
+
uninstallProtocolCc: () => uninstallProtocolCc,
|
|
10957
|
+
uninstallProtocolCcUser: () => uninstallProtocolCcUser
|
|
10745
10958
|
});
|
|
10746
10959
|
function createAdapter2(_options) {
|
|
10747
10960
|
return {
|
|
@@ -10764,6 +10977,7 @@ var init_dist3 = __esm({
|
|
|
10764
10977
|
init_hooks2();
|
|
10765
10978
|
init_protocol2();
|
|
10766
10979
|
init_scan();
|
|
10980
|
+
init_protocol_user();
|
|
10767
10981
|
}
|
|
10768
10982
|
});
|
|
10769
10983
|
|
|
@@ -11476,15 +11690,15 @@ var init_dist4 = __esm({
|
|
|
11476
11690
|
});
|
|
11477
11691
|
|
|
11478
11692
|
// packages/adapter-codex/dist/shared.js
|
|
11479
|
-
import { homedir as
|
|
11480
|
-
import { join as
|
|
11693
|
+
import { homedir as homedir11 } from "node:os";
|
|
11694
|
+
import { join as join16 } from "node:path";
|
|
11481
11695
|
function resolvePaths(options) {
|
|
11482
|
-
const homeDir = options?.homeDir ??
|
|
11696
|
+
const homeDir = options?.homeDir ?? homedir11();
|
|
11483
11697
|
const projectDir = options?.projectDir ?? process.cwd();
|
|
11484
|
-
return { homeDir, projectDir, codexHome:
|
|
11698
|
+
return { homeDir, projectDir, codexHome: join16(homeDir, ".codex") };
|
|
11485
11699
|
}
|
|
11486
|
-
function wingmanStateRoot(
|
|
11487
|
-
return
|
|
11700
|
+
function wingmanStateRoot(paths3) {
|
|
11701
|
+
return join16(paths3.homeDir, ".wingman");
|
|
11488
11702
|
}
|
|
11489
11703
|
function isTable(value) {
|
|
11490
11704
|
return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
|
|
@@ -11793,26 +12007,26 @@ var init_toml_edit = __esm({
|
|
|
11793
12007
|
});
|
|
11794
12008
|
|
|
11795
12009
|
// packages/adapter-codex/dist/actions.js
|
|
11796
|
-
import { existsSync as
|
|
11797
|
-
import { basename as
|
|
12010
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3, writeFileSync as writeFileSync8 } from "node:fs";
|
|
12011
|
+
import { basename as basename7, dirname as dirname11, join as join17 } from "node:path";
|
|
11798
12012
|
async function planAction(action, options) {
|
|
11799
|
-
const
|
|
11800
|
-
const resolved = resolveToggle(action,
|
|
12013
|
+
const paths3 = resolvePaths(options);
|
|
12014
|
+
const resolved = resolveToggle(action, paths3);
|
|
11801
12015
|
return {
|
|
11802
12016
|
harness: "codex",
|
|
11803
12017
|
action,
|
|
11804
12018
|
writes: [
|
|
11805
12019
|
{ file: resolved.file, kind: "modify", before: resolved.before, after: resolved.after }
|
|
11806
12020
|
],
|
|
11807
|
-
backupDir:
|
|
11808
|
-
references: scanReferences(collectCorpus(
|
|
12021
|
+
backupDir: nextBackupDir4(paths3),
|
|
12022
|
+
references: scanReferences(collectCorpus(paths3), resolved.bareName),
|
|
11809
12023
|
// §4b 地面真值:config.toml 启动时读,外改对运行中会话不生效 → 如实报 next_session
|
|
11810
12024
|
effectiveAt: "next_session"
|
|
11811
12025
|
};
|
|
11812
12026
|
}
|
|
11813
12027
|
async function applyAction(plan, options) {
|
|
11814
12028
|
try {
|
|
11815
|
-
const
|
|
12029
|
+
const paths3 = resolvePaths(options);
|
|
11816
12030
|
if (plan.harness !== "codex") {
|
|
11817
12031
|
return { ok: false, error: `plan.harness=${String(plan.harness)} \u4E0D\u662F codex,\u62D2\u7EDD\u6267\u884C` };
|
|
11818
12032
|
}
|
|
@@ -11823,38 +12037,38 @@ async function applyAction(plan, options) {
|
|
|
11823
12037
|
error: "plan.writes \u4E0D\u662F\u672C adapter \u4EA7\u51FA\u7684\u5F62\u72B6(\u5E94\u6070\u4E3A\u4E00\u5904 modify),\u62D2\u7EDD\u6267\u884C"
|
|
11824
12038
|
};
|
|
11825
12039
|
}
|
|
11826
|
-
const backupsRoot =
|
|
11827
|
-
if (
|
|
12040
|
+
const backupsRoot = join17(wingmanStateRoot(paths3), "backups");
|
|
12041
|
+
if (dirname11(plan.backupDir) !== backupsRoot) {
|
|
11828
12042
|
return { ok: false, error: `backupDir \u4E0D\u5728 wingman \u5907\u4EFD\u6839(${backupsRoot})\u4E0B,\u62D2\u7EDD\u6267\u884C` };
|
|
11829
12043
|
}
|
|
11830
|
-
const currentRaw =
|
|
12044
|
+
const currentRaw = readFileSync10(write.file);
|
|
11831
12045
|
if (!currentRaw.equals(Buffer.from(write.before, "utf8"))) {
|
|
11832
12046
|
return { ok: false, error: `\u6587\u4EF6\u5728 plan \u4E4B\u540E\u88AB\u4FEE\u6539(${write.file}),\u62D2\u7EDD\u6267\u884C;\u8BF7\u91CD\u65B0 plan` };
|
|
11833
12047
|
}
|
|
11834
|
-
const resolved = resolveToggle(plan.action,
|
|
12048
|
+
const resolved = resolveToggle(plan.action, paths3);
|
|
11835
12049
|
if (resolved.file !== write.file) {
|
|
11836
12050
|
return { ok: false, error: "plan.writes \u7684\u76EE\u6807\u6587\u4EF6\u4E0E itemId \u5BF9\u4E0D\u4E0A,\u62D2\u7EDD\u6267\u884C" };
|
|
11837
12051
|
}
|
|
11838
12052
|
if (resolved.after !== write.after) {
|
|
11839
12053
|
return { ok: false, error: "plan \u4E0E\u672C adapter \u7684\u63A8\u6F14\u4E0D\u4E00\u81F4,\u62D2\u7EDD\u6267\u884C;\u8BF7\u91CD\u65B0 plan" };
|
|
11840
12054
|
}
|
|
11841
|
-
|
|
11842
|
-
|
|
11843
|
-
|
|
12055
|
+
mkdirSync7(plan.backupDir, { recursive: true });
|
|
12056
|
+
writeFileSync8(join17(plan.backupDir, basename7(write.file)), currentRaw);
|
|
12057
|
+
writeFileSync8(write.file, write.after);
|
|
11844
12058
|
return { ok: true, backupDir: plan.backupDir };
|
|
11845
12059
|
} catch (error) {
|
|
11846
12060
|
return { ok: false, error: error.message };
|
|
11847
12061
|
}
|
|
11848
12062
|
}
|
|
11849
|
-
function
|
|
12063
|
+
function nextBackupDir4(paths3) {
|
|
11850
12064
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
11851
|
-
const base =
|
|
11852
|
-
let dir =
|
|
11853
|
-
for (let n = 1;
|
|
11854
|
-
dir =
|
|
12065
|
+
const base = join17(wingmanStateRoot(paths3), "backups");
|
|
12066
|
+
let dir = join17(base, stamp);
|
|
12067
|
+
for (let n = 1; existsSync10(dir); n += 1)
|
|
12068
|
+
dir = join17(base, `${stamp}-${n}`);
|
|
11855
12069
|
return dir;
|
|
11856
12070
|
}
|
|
11857
|
-
function resolveToggle(action,
|
|
12071
|
+
function resolveToggle(action, paths3) {
|
|
11858
12072
|
if (action.kind !== "toggle") {
|
|
11859
12073
|
throw new Error(`\u672A\u77E5\u52A8\u4F5C\u79CD\u7C7B:${String(action.kind)}(v1 \u4EC5 toggle \u8D70 plan\u2192apply)`);
|
|
11860
12074
|
}
|
|
@@ -11865,10 +12079,10 @@ function resolveToggle(action, paths) {
|
|
|
11865
12079
|
const slot = m[1];
|
|
11866
12080
|
const source = m[2];
|
|
11867
12081
|
const nativeName = m[3];
|
|
11868
|
-
const file = source === "user" ?
|
|
11869
|
-
if (!
|
|
12082
|
+
const file = source === "user" ? join17(paths3.codexHome, "config.toml") : join17(paths3.projectDir, ".codex", "config.toml");
|
|
12083
|
+
if (!existsSync10(file))
|
|
11870
12084
|
throw new Error(`itemId \u627E\u4E0D\u5230:\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728(${file})`);
|
|
11871
|
-
const before =
|
|
12085
|
+
const before = readFileSync10(file, "utf8");
|
|
11872
12086
|
let table;
|
|
11873
12087
|
try {
|
|
11874
12088
|
table = parse3(before);
|
|
@@ -12089,15 +12303,15 @@ function verifyEdit(table, edit, file) {
|
|
|
12089
12303
|
throw new Error(`\u7F16\u8F91\u7ED3\u679C\u4E0E\u671F\u671B\u7684\u6700\u5C0F\u53D8\u66F4\u4E0D\u4E00\u81F4,\u62D2\u7EDD\u5199\u5165(${file})`);
|
|
12090
12304
|
}
|
|
12091
12305
|
}
|
|
12092
|
-
function collectCorpus(
|
|
12306
|
+
function collectCorpus(paths3) {
|
|
12093
12307
|
const candidates = [
|
|
12094
|
-
|
|
12095
|
-
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
...listFilesRecursive(
|
|
12308
|
+
join17(paths3.codexHome, "AGENTS.md"),
|
|
12309
|
+
join17(paths3.projectDir, "AGENTS.md"),
|
|
12310
|
+
join17(paths3.codexHome, "config.toml"),
|
|
12311
|
+
join17(paths3.projectDir, ".codex", "config.toml"),
|
|
12312
|
+
join17(paths3.codexHome, "hooks.json"),
|
|
12313
|
+
join17(paths3.projectDir, ".codex", "hooks.json"),
|
|
12314
|
+
...listFilesRecursive(join17(paths3.codexHome, "prompts"))
|
|
12101
12315
|
];
|
|
12102
12316
|
const sources = [];
|
|
12103
12317
|
for (const file of candidates) {
|
|
@@ -12107,7 +12321,7 @@ function collectCorpus(paths) {
|
|
|
12107
12321
|
} catch {
|
|
12108
12322
|
continue;
|
|
12109
12323
|
}
|
|
12110
|
-
sources.push({ file, text:
|
|
12324
|
+
sources.push({ file, text: readFileSync10(file, "utf8") });
|
|
12111
12325
|
}
|
|
12112
12326
|
return sources;
|
|
12113
12327
|
}
|
|
@@ -12120,7 +12334,7 @@ function listFilesRecursive(dir) {
|
|
|
12120
12334
|
}
|
|
12121
12335
|
const files = [];
|
|
12122
12336
|
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
12123
|
-
const path =
|
|
12337
|
+
const path = join17(dir, entry.name);
|
|
12124
12338
|
if (entry.isDirectory())
|
|
12125
12339
|
files.push(...listFilesRecursive(path));
|
|
12126
12340
|
else if (entry.isFile())
|
|
@@ -12187,17 +12401,17 @@ var init_actions2 = __esm({
|
|
|
12187
12401
|
|
|
12188
12402
|
// packages/adapter-codex/dist/hooks.js
|
|
12189
12403
|
import { spawnSync } from "node:child_process";
|
|
12190
|
-
import { existsSync as
|
|
12191
|
-
import { basename as
|
|
12404
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync11, realpathSync, rmSync as rmSync6, writeFileSync as writeFileSync9 } from "node:fs";
|
|
12405
|
+
import { basename as basename8, dirname as dirname12, join as join18 } from "node:path";
|
|
12192
12406
|
async function installHooks(port, options) {
|
|
12193
12407
|
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
12194
12408
|
throw new Error(`\u975E\u6CD5\u7AEF\u53E3:${port}`);
|
|
12195
12409
|
}
|
|
12196
|
-
const
|
|
12197
|
-
const root = wingmanStateRoot(
|
|
12198
|
-
const scriptPath =
|
|
12199
|
-
const configPath =
|
|
12200
|
-
const raw =
|
|
12410
|
+
const paths3 = resolvePaths(options);
|
|
12411
|
+
const root = wingmanStateRoot(paths3);
|
|
12412
|
+
const scriptPath = join18(root, FORWARD_SCRIPT_NAME);
|
|
12413
|
+
const configPath = join18(paths3.codexHome, "config.toml");
|
|
12414
|
+
const raw = existsSync11(configPath) ? readFileSync11(configPath) : void 0;
|
|
12201
12415
|
const text = raw?.toString("utf8") ?? "";
|
|
12202
12416
|
const { before, after, remainder, block } = splitManagedBlock(text, configPath);
|
|
12203
12417
|
const lineEnding = preferredLineEnding(text);
|
|
@@ -12206,8 +12420,8 @@ async function installHooks(port, options) {
|
|
|
12206
12420
|
if (block !== void 0 && knownBlock === void 0) {
|
|
12207
12421
|
throw new Error(`Wingman Codex hook \u53D7\u7BA1\u5757\u5DF2\u88AB\u4FEE\u6539\u6216\u6B8B\u7F3A(${configPath}),\u62D2\u7EDD\u8C0E\u62A5\u63A5\u7EBF\u6210\u529F;\u8BF7\u5148\u4ECE <wingman\u6839>/backups/ \u6062\u590D\u5B8C\u6574\u5757,\u6216\u4EBA\u5DE5\u6838\u5BF9\u540E\u79FB\u9664\u8BE5\u53D7\u7BA1\u5757\u518D\u91CD\u65B0\u5B89\u88C5\u5E76\u4FE1\u4EFB`);
|
|
12208
12422
|
}
|
|
12209
|
-
|
|
12210
|
-
|
|
12423
|
+
mkdirSync8(root, { recursive: true });
|
|
12424
|
+
writeFileSync9(scriptPath, FORWARD_SCRIPT);
|
|
12211
12425
|
const statePath2 = hooksStatePath(root);
|
|
12212
12426
|
const prior = readState5(statePath2);
|
|
12213
12427
|
if (knownBlock !== void 0 && knownBlock.state === void 0) {
|
|
@@ -12236,7 +12450,7 @@ async function installHooks(port, options) {
|
|
|
12236
12450
|
...backupDir !== void 0 ? { backupDir } : {}
|
|
12237
12451
|
});
|
|
12238
12452
|
const state = hasStateOutsideBlock ? "" : knownBlock.state;
|
|
12239
|
-
|
|
12453
|
+
writeFileSync9(configPath, before + knownBlock.managedBlock + state + after);
|
|
12240
12454
|
return;
|
|
12241
12455
|
}
|
|
12242
12456
|
const original = prior?.original ?? (raw === void 0 ? { existed: false } : { existed: true, base64: raw.toString("base64") });
|
|
@@ -12252,17 +12466,17 @@ async function installHooks(port, options) {
|
|
|
12252
12466
|
let base = remainder;
|
|
12253
12467
|
if (base !== "" && !base.endsWith("\n"))
|
|
12254
12468
|
base += lineEnding;
|
|
12255
|
-
|
|
12256
|
-
|
|
12469
|
+
mkdirSync8(paths3.codexHome, { recursive: true });
|
|
12470
|
+
writeFileSync9(configPath, base + newBlock);
|
|
12257
12471
|
}
|
|
12258
12472
|
async function uninstallHooks(options) {
|
|
12259
|
-
const
|
|
12260
|
-
const root = wingmanStateRoot(
|
|
12261
|
-
const scriptPath =
|
|
12473
|
+
const paths3 = resolvePaths(options);
|
|
12474
|
+
const root = wingmanStateRoot(paths3);
|
|
12475
|
+
const scriptPath = join18(root, FORWARD_SCRIPT_NAME);
|
|
12262
12476
|
const statePath2 = hooksStatePath(root);
|
|
12263
|
-
const configPath =
|
|
12477
|
+
const configPath = join18(paths3.codexHome, "config.toml");
|
|
12264
12478
|
const state = readState5(statePath2);
|
|
12265
|
-
const raw =
|
|
12479
|
+
const raw = existsSync11(configPath) ? readFileSync11(configPath) : void 0;
|
|
12266
12480
|
if (raw !== void 0) {
|
|
12267
12481
|
const text = raw.toString("utf8");
|
|
12268
12482
|
const { before, after, remainder, block } = splitManagedBlock(text, configPath);
|
|
@@ -12275,34 +12489,34 @@ async function uninstallHooks(options) {
|
|
|
12275
12489
|
const preservedState = hasHooksState(remainder) ? "" : knownBlock.state ?? "";
|
|
12276
12490
|
const restored = restoreTarget(before + preservedState + after, state);
|
|
12277
12491
|
if (restored === null)
|
|
12278
|
-
|
|
12492
|
+
rmSync6(configPath);
|
|
12279
12493
|
else
|
|
12280
|
-
|
|
12494
|
+
writeFileSync9(configPath, restored);
|
|
12281
12495
|
}
|
|
12282
12496
|
}
|
|
12283
|
-
|
|
12284
|
-
|
|
12497
|
+
rmSync6(scriptPath, { force: true });
|
|
12498
|
+
rmSync6(statePath2, { force: true });
|
|
12285
12499
|
}
|
|
12286
|
-
function hasManagedHooks2(
|
|
12287
|
-
const configPath =
|
|
12288
|
-
if (!
|
|
12500
|
+
function hasManagedHooks2(paths3) {
|
|
12501
|
+
const configPath = join18(paths3.codexHome, "config.toml");
|
|
12502
|
+
if (!existsSync11(configPath))
|
|
12289
12503
|
return false;
|
|
12290
12504
|
try {
|
|
12291
|
-
const { block } = splitManagedBlock(
|
|
12292
|
-
return block !== void 0 && inspectManagedBlock(block,
|
|
12505
|
+
const { block } = splitManagedBlock(readFileSync11(configPath, "utf8"), configPath);
|
|
12506
|
+
return block !== void 0 && inspectManagedBlock(block, join18(wingmanStateRoot(paths3), FORWARD_SCRIPT_NAME)) !== void 0;
|
|
12293
12507
|
} catch {
|
|
12294
12508
|
return false;
|
|
12295
12509
|
}
|
|
12296
12510
|
}
|
|
12297
12511
|
function feedbackSignalsCodex(options) {
|
|
12298
|
-
const
|
|
12299
|
-
const configPath =
|
|
12512
|
+
const paths3 = resolvePaths(options);
|
|
12513
|
+
const configPath = join18(paths3.codexHome, "config.toml");
|
|
12300
12514
|
const wiredEvents = [];
|
|
12301
|
-
if (
|
|
12515
|
+
if (existsSync11(configPath)) {
|
|
12302
12516
|
try {
|
|
12303
|
-
const { block } = splitManagedBlock(
|
|
12517
|
+
const { block } = splitManagedBlock(readFileSync11(configPath, "utf8"), configPath);
|
|
12304
12518
|
if (block !== void 0) {
|
|
12305
|
-
const knownBlock = inspectManagedBlock(block,
|
|
12519
|
+
const knownBlock = inspectManagedBlock(block, join18(wingmanStateRoot(paths3), FORWARD_SCRIPT_NAME));
|
|
12306
12520
|
const hooks = knownBlock === void 0 ? void 0 : parse3(normalizeLineEndings(knownBlock.managedBlock)).hooks;
|
|
12307
12521
|
if (isTable(hooks)) {
|
|
12308
12522
|
for (const [event, groups] of Object.entries(hooks)) {
|
|
@@ -12343,7 +12557,7 @@ function restoreTarget(remainder, state) {
|
|
|
12343
12557
|
}
|
|
12344
12558
|
function resolveNodeExecutable(probe = {}) {
|
|
12345
12559
|
const execPath = probe.execPath ?? process.execPath;
|
|
12346
|
-
const exists = probe.exists ??
|
|
12560
|
+
const exists = probe.exists ?? existsSync11;
|
|
12347
12561
|
let executable = isNodeExecutable(execPath) ? execPath : void 0;
|
|
12348
12562
|
if (executable === void 0) {
|
|
12349
12563
|
const loginShellWhich = probe.loginShellWhich ?? defaultLoginShellWhich;
|
|
@@ -12390,13 +12604,13 @@ function defaultRealpath(path) {
|
|
|
12390
12604
|
}
|
|
12391
12605
|
}
|
|
12392
12606
|
function defaultLoginShellWhich(shell) {
|
|
12393
|
-
const
|
|
12607
|
+
const result5 = spawnSync(shell, ["-lc", "command -v node"], {
|
|
12394
12608
|
encoding: "utf8",
|
|
12395
12609
|
timeout: 3e3
|
|
12396
12610
|
});
|
|
12397
|
-
if (
|
|
12611
|
+
if (result5.error !== void 0)
|
|
12398
12612
|
return void 0;
|
|
12399
|
-
return
|
|
12613
|
+
return result5.stdout.trim() || void 0;
|
|
12400
12614
|
}
|
|
12401
12615
|
function buildManagedBlock(scriptPath, nodeExecutable = "node") {
|
|
12402
12616
|
return buildManagedBlockForCommand(`${nodeExecutable} "${scriptPath}"`);
|
|
@@ -12548,28 +12762,28 @@ function hasHooksState(text) {
|
|
|
12548
12762
|
}
|
|
12549
12763
|
function backupFile(root, filePath, contents) {
|
|
12550
12764
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
12551
|
-
let dir =
|
|
12552
|
-
for (let n = 1;
|
|
12553
|
-
dir =
|
|
12554
|
-
|
|
12555
|
-
|
|
12765
|
+
let dir = join18(root, "backups", stamp);
|
|
12766
|
+
for (let n = 1; existsSync11(dir); n += 1)
|
|
12767
|
+
dir = join18(root, "backups", `${stamp}-${n}`);
|
|
12768
|
+
mkdirSync8(dir, { recursive: true });
|
|
12769
|
+
writeFileSync9(join18(dir, basename8(filePath)), contents);
|
|
12556
12770
|
return dir;
|
|
12557
12771
|
}
|
|
12558
12772
|
function hooksStatePath(root) {
|
|
12559
|
-
return
|
|
12773
|
+
return join18(root, "state", "codex-hooks.json");
|
|
12560
12774
|
}
|
|
12561
12775
|
function readState5(statePath2) {
|
|
12562
|
-
if (!
|
|
12776
|
+
if (!existsSync11(statePath2))
|
|
12563
12777
|
return void 0;
|
|
12564
12778
|
try {
|
|
12565
|
-
return JSON.parse(
|
|
12779
|
+
return JSON.parse(readFileSync11(statePath2, "utf8"));
|
|
12566
12780
|
} catch {
|
|
12567
12781
|
return void 0;
|
|
12568
12782
|
}
|
|
12569
12783
|
}
|
|
12570
12784
|
function writeState5(statePath2, state) {
|
|
12571
|
-
|
|
12572
|
-
|
|
12785
|
+
mkdirSync8(dirname12(statePath2), { recursive: true });
|
|
12786
|
+
writeFileSync9(statePath2, `${JSON.stringify(state, null, 2)}
|
|
12573
12787
|
`);
|
|
12574
12788
|
}
|
|
12575
12789
|
function deepEqual3(a, b) {
|
|
@@ -12725,15 +12939,15 @@ process.stdin.on('end', async () => {
|
|
|
12725
12939
|
});
|
|
12726
12940
|
|
|
12727
12941
|
// packages/adapter-codex/dist/scan.js
|
|
12728
|
-
import { existsSync as
|
|
12729
|
-
import { dirname as
|
|
12942
|
+
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync12, statSync as statSync4 } from "node:fs";
|
|
12943
|
+
import { dirname as dirname13, isAbsolute as isAbsolute3, join as join19, resolve as resolve7 } from "node:path";
|
|
12730
12944
|
async function detect(options) {
|
|
12731
12945
|
const { codexHome } = resolvePaths(options);
|
|
12732
|
-
return { installed:
|
|
12946
|
+
return { installed: existsSync12(codexHome) };
|
|
12733
12947
|
}
|
|
12734
12948
|
async function scan(options) {
|
|
12735
|
-
const
|
|
12736
|
-
const layers = loadConfigLayers(
|
|
12949
|
+
const paths3 = resolvePaths(options);
|
|
12950
|
+
const layers = loadConfigLayers(paths3);
|
|
12737
12951
|
const slots = {
|
|
12738
12952
|
base: [],
|
|
12739
12953
|
rules: [],
|
|
@@ -12742,14 +12956,14 @@ async function scan(options) {
|
|
|
12742
12956
|
gates: [],
|
|
12743
12957
|
history: []
|
|
12744
12958
|
};
|
|
12745
|
-
collectRules(slots.rules,
|
|
12959
|
+
collectRules(slots.rules, paths3, layers);
|
|
12746
12960
|
for (const layer of layers) {
|
|
12747
12961
|
collectBase(slots.base, layer);
|
|
12748
12962
|
collectSkills(slots.skills, layer);
|
|
12749
12963
|
collectTools(slots.tools, layer);
|
|
12750
12964
|
collectGates(slots.gates, layer);
|
|
12751
12965
|
}
|
|
12752
|
-
collectHistory(slots.history,
|
|
12966
|
+
collectHistory(slots.history, paths3, layers);
|
|
12753
12967
|
assertUniqueIds(slots);
|
|
12754
12968
|
return {
|
|
12755
12969
|
harness: "codex",
|
|
@@ -12759,21 +12973,21 @@ async function scan(options) {
|
|
|
12759
12973
|
// actions:M3 起 toggle(plan→apply)/scan_references(命中随 plan)已落地;
|
|
12760
12974
|
// open_editor 是面板用 nativePath 跳转的即时动作,无需 adapter 方法
|
|
12761
12975
|
capabilities: {
|
|
12762
|
-
live: hasManagedHooks2(
|
|
12976
|
+
live: hasManagedHooks2(paths3) ? "push" : "none",
|
|
12763
12977
|
actions: ["toggle", "open_editor", "scan_references"]
|
|
12764
12978
|
}
|
|
12765
12979
|
};
|
|
12766
12980
|
}
|
|
12767
|
-
function loadConfigLayers(
|
|
12981
|
+
function loadConfigLayers(paths3) {
|
|
12768
12982
|
const candidates = [
|
|
12769
|
-
["user",
|
|
12770
|
-
["project",
|
|
12983
|
+
["user", join19(paths3.codexHome, "config.toml")],
|
|
12984
|
+
["project", join19(paths3.projectDir, ".codex", "config.toml")]
|
|
12771
12985
|
];
|
|
12772
12986
|
const layers = [];
|
|
12773
12987
|
for (const [source, path] of candidates) {
|
|
12774
12988
|
if (fileSize(path) === void 0)
|
|
12775
12989
|
continue;
|
|
12776
|
-
const text =
|
|
12990
|
+
const text = readFileSync12(path, "utf8");
|
|
12777
12991
|
try {
|
|
12778
12992
|
layers.push({ source, path, table: parse3(text) });
|
|
12779
12993
|
} catch (error) {
|
|
@@ -12782,10 +12996,10 @@ function loadConfigLayers(paths) {
|
|
|
12782
12996
|
}
|
|
12783
12997
|
return layers;
|
|
12784
12998
|
}
|
|
12785
|
-
function collectRules(out,
|
|
12999
|
+
function collectRules(out, paths3, layers) {
|
|
12786
13000
|
const agentsChain = [
|
|
12787
|
-
["user",
|
|
12788
|
-
["project",
|
|
13001
|
+
["user", join19(paths3.codexHome, "AGENTS.md")],
|
|
13002
|
+
["project", join19(paths3.projectDir, "AGENTS.md")]
|
|
12789
13003
|
];
|
|
12790
13004
|
for (const [source, file] of agentsChain) {
|
|
12791
13005
|
const size = fileSize(file);
|
|
@@ -12820,7 +13034,7 @@ function collectRules(out, paths, layers) {
|
|
|
12820
13034
|
}
|
|
12821
13035
|
const instructionsFile = layer.table.model_instructions_file;
|
|
12822
13036
|
if (typeof instructionsFile === "string") {
|
|
12823
|
-
const filePath = isAbsolute3(instructionsFile) ? instructionsFile :
|
|
13037
|
+
const filePath = isAbsolute3(instructionsFile) ? instructionsFile : resolve7(dirname13(layer.path), instructionsFile);
|
|
12824
13038
|
const item = {
|
|
12825
13039
|
id: `codex:rules:${layer.source}:model_instructions_file`,
|
|
12826
13040
|
slot: "rules",
|
|
@@ -12919,8 +13133,8 @@ function collectGates(out, layer) {
|
|
|
12919
13133
|
});
|
|
12920
13134
|
}
|
|
12921
13135
|
}
|
|
12922
|
-
function collectHistory(out,
|
|
12923
|
-
const historyFile =
|
|
13136
|
+
function collectHistory(out, paths3, layers) {
|
|
13137
|
+
const historyFile = join19(paths3.codexHome, "history.jsonl");
|
|
12924
13138
|
const historyBytes = fileSize(historyFile);
|
|
12925
13139
|
if (historyBytes !== void 0) {
|
|
12926
13140
|
out.push({
|
|
@@ -12935,7 +13149,7 @@ function collectHistory(out, paths, layers) {
|
|
|
12935
13149
|
});
|
|
12936
13150
|
}
|
|
12937
13151
|
const configured = layers.find((layer) => layer.source === "user")?.table.log_dir;
|
|
12938
|
-
const logDir = typeof configured === "string" ? expandPath(configured,
|
|
13152
|
+
const logDir = typeof configured === "string" ? expandPath(configured, paths3) : join19(paths3.codexHome, "log");
|
|
12939
13153
|
if (isDirectory(logDir)) {
|
|
12940
13154
|
out.push({
|
|
12941
13155
|
id: "codex:history:user:log_dir",
|
|
@@ -12949,10 +13163,10 @@ function collectHistory(out, paths, layers) {
|
|
|
12949
13163
|
});
|
|
12950
13164
|
}
|
|
12951
13165
|
}
|
|
12952
|
-
function expandPath(value,
|
|
13166
|
+
function expandPath(value, paths3) {
|
|
12953
13167
|
if (value === "~" || value.startsWith("~/"))
|
|
12954
|
-
return
|
|
12955
|
-
return isAbsolute3(value) ? value :
|
|
13168
|
+
return join19(paths3.homeDir, value.slice(2));
|
|
13169
|
+
return isAbsolute3(value) ? value : resolve7(paths3.codexHome, value);
|
|
12956
13170
|
}
|
|
12957
13171
|
function assertUniqueIds(slots) {
|
|
12958
13172
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -12983,7 +13197,7 @@ function isDirectory(path) {
|
|
|
12983
13197
|
function directoryBytes(dir) {
|
|
12984
13198
|
let total = 0;
|
|
12985
13199
|
for (const entry of readdirSync4(dir, { withFileTypes: true })) {
|
|
12986
|
-
const entryPath =
|
|
13200
|
+
const entryPath = join19(dir, entry.name);
|
|
12987
13201
|
if (entry.isDirectory())
|
|
12988
13202
|
total += directoryBytes(entryPath);
|
|
12989
13203
|
else if (entry.isFile())
|
|
@@ -13005,54 +13219,54 @@ var init_scan2 = __esm({
|
|
|
13005
13219
|
});
|
|
13006
13220
|
|
|
13007
13221
|
// packages/adapter-codex/dist/protocol.js
|
|
13008
|
-
import { existsSync as
|
|
13009
|
-
import { basename as
|
|
13222
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync13, rmSync as rmSync7, writeFileSync as writeFileSync10 } from "node:fs";
|
|
13223
|
+
import { basename as basename9, dirname as dirname14, join as join20, resolve as resolve8 } from "node:path";
|
|
13010
13224
|
function protocolStatusCodex(options) {
|
|
13011
|
-
const
|
|
13012
|
-
if (!
|
|
13013
|
-
return status2(
|
|
13225
|
+
const paths3 = resolveOptions3(options);
|
|
13226
|
+
if (!existsSync13(paths3.targetPath))
|
|
13227
|
+
return status2(paths3.targetPath, "not_installed");
|
|
13014
13228
|
try {
|
|
13015
|
-
const file = readAgents2(
|
|
13229
|
+
const file = readAgents2(paths3.targetPath);
|
|
13016
13230
|
if (file.identity === void 0)
|
|
13017
|
-
return status2(
|
|
13231
|
+
return status2(paths3.targetPath, "not_installed");
|
|
13018
13232
|
const state = stateForIdentity3(file.identity);
|
|
13019
|
-
return status2(
|
|
13233
|
+
return status2(paths3.targetPath, state, file.identity);
|
|
13020
13234
|
} catch (error) {
|
|
13021
|
-
return status2(
|
|
13235
|
+
return status2(paths3.targetPath, "invalid", void 0, error.message);
|
|
13022
13236
|
}
|
|
13023
13237
|
}
|
|
13024
13238
|
function installProtocolCodex(options) {
|
|
13025
|
-
const
|
|
13026
|
-
const existing =
|
|
13239
|
+
const paths3 = resolveOptions3(options);
|
|
13240
|
+
const existing = existsSync13(paths3.targetPath) ? readAgents2(paths3.targetPath) : void 0;
|
|
13027
13241
|
const previousState = stateForIdentity3(existing?.identity);
|
|
13028
13242
|
if (previousState === "installed") {
|
|
13029
|
-
return
|
|
13243
|
+
return result4(paths3.targetPath, "install", false, previousState, existing?.text ?? "", true);
|
|
13030
13244
|
}
|
|
13031
13245
|
if (previousState === "modified")
|
|
13032
|
-
throw modifiedError3(
|
|
13246
|
+
throw modifiedError3(paths3.targetPath, "\u5B89\u88C5");
|
|
13033
13247
|
const before = existing?.text ?? "";
|
|
13034
13248
|
const lineEnding = preferredMarkdownLineEnding(before);
|
|
13035
13249
|
const block = buildPlanProtocolBlock().replaceAll("\n", lineEnding);
|
|
13036
13250
|
const after = existing?.split.block ? existing.split.before + block + existing.split.after : appendBlock2(before, block, lineEnding);
|
|
13037
|
-
const installedRemainder = splitPlanProtocolBlock(after,
|
|
13038
|
-
const backupDir =
|
|
13039
|
-
if (!
|
|
13040
|
-
const prior = readState6(
|
|
13041
|
-
|
|
13042
|
-
writeState6(
|
|
13251
|
+
const installedRemainder = splitPlanProtocolBlock(after, paths3.targetPath).remainder;
|
|
13252
|
+
const backupDir = nextBackupDir5(paths3.homeDir);
|
|
13253
|
+
if (!paths3.dryRun) {
|
|
13254
|
+
const prior = readState6(paths3.statePath, paths3.targetPath);
|
|
13255
|
+
backupTarget4(backupDir, paths3.targetPath, existing?.bytes);
|
|
13256
|
+
writeState6(paths3.statePath, {
|
|
13043
13257
|
version: 1,
|
|
13044
|
-
projectDir:
|
|
13045
|
-
targetPath:
|
|
13258
|
+
projectDir: paths3.projectDir,
|
|
13259
|
+
targetPath: paths3.targetPath,
|
|
13046
13260
|
protocolVersion: PLAN_PROTOCOL_VERSION,
|
|
13047
13261
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13048
13262
|
backupDir,
|
|
13049
13263
|
installedRemainderSha256: sha256Hex(installedRemainder),
|
|
13050
13264
|
original: prior?.original ?? (existing === void 0 ? { existed: false } : { existed: true, base64: existing.bytes.toString("base64") })
|
|
13051
13265
|
});
|
|
13052
|
-
|
|
13266
|
+
writeFileSync10(paths3.targetPath, after);
|
|
13053
13267
|
}
|
|
13054
13268
|
return {
|
|
13055
|
-
...
|
|
13269
|
+
...result4(paths3.targetPath, "install", true, previousState, before, true),
|
|
13056
13270
|
state: "installed",
|
|
13057
13271
|
version: PLAN_PROTOCOL_VERSION,
|
|
13058
13272
|
after,
|
|
@@ -13061,33 +13275,33 @@ function installProtocolCodex(options) {
|
|
|
13061
13275
|
};
|
|
13062
13276
|
}
|
|
13063
13277
|
function uninstallProtocolCodex(options) {
|
|
13064
|
-
const
|
|
13065
|
-
if (!
|
|
13066
|
-
return
|
|
13278
|
+
const paths3 = resolveOptions3(options);
|
|
13279
|
+
if (!existsSync13(paths3.targetPath)) {
|
|
13280
|
+
return result4(paths3.targetPath, "uninstall", false, "not_installed", "", false);
|
|
13067
13281
|
}
|
|
13068
|
-
const existing = readAgents2(
|
|
13282
|
+
const existing = readAgents2(paths3.targetPath);
|
|
13069
13283
|
if (existing.identity === void 0) {
|
|
13070
|
-
return
|
|
13284
|
+
return result4(paths3.targetPath, "uninstall", false, "not_installed", existing.text, true);
|
|
13071
13285
|
}
|
|
13072
13286
|
const previousState = stateForIdentity3(existing.identity);
|
|
13073
13287
|
if (previousState === "modified")
|
|
13074
|
-
throw modifiedError3(
|
|
13075
|
-
const state = readState6(
|
|
13288
|
+
throw modifiedError3(paths3.targetPath, "\u5378\u8F7D");
|
|
13289
|
+
const state = readState6(paths3.statePath, paths3.targetPath);
|
|
13076
13290
|
const canRestore = state !== void 0 && sha256Hex(existing.split.remainder) === state.installedRemainderSha256;
|
|
13077
13291
|
const restored = canRestore ? originalBytes2(state) : void 0;
|
|
13078
13292
|
const deleteTarget = canRestore ? state?.original.existed === false : existing.split.remainder.trim() === "";
|
|
13079
13293
|
const after = deleteTarget ? "" : restored?.toString("utf8") ?? existing.split.remainder;
|
|
13080
|
-
const backupDir =
|
|
13081
|
-
if (!
|
|
13082
|
-
|
|
13294
|
+
const backupDir = nextBackupDir5(paths3.homeDir);
|
|
13295
|
+
if (!paths3.dryRun) {
|
|
13296
|
+
backupTarget4(backupDir, paths3.targetPath, existing.bytes);
|
|
13083
13297
|
if (deleteTarget)
|
|
13084
|
-
|
|
13298
|
+
rmSync7(paths3.targetPath, { force: true });
|
|
13085
13299
|
else
|
|
13086
|
-
|
|
13087
|
-
|
|
13300
|
+
writeFileSync10(paths3.targetPath, restored ?? existing.split.remainder);
|
|
13301
|
+
rmSync7(paths3.statePath, { force: true });
|
|
13088
13302
|
}
|
|
13089
13303
|
return {
|
|
13090
|
-
...
|
|
13304
|
+
...result4(paths3.targetPath, "uninstall", true, previousState, existing.text, !deleteTarget),
|
|
13091
13305
|
state: "not_installed",
|
|
13092
13306
|
message: canRestore ? SHARED_MESSAGE2 : `${SHARED_MESSAGE2}\uFF1B\u5DF2\u79FB\u9664\u5757\u5E76\u4FDD\u7559\u7528\u6237\u6539\u52A8`,
|
|
13093
13307
|
after,
|
|
@@ -13098,14 +13312,14 @@ function uninstallProtocolCodex(options) {
|
|
|
13098
13312
|
}
|
|
13099
13313
|
function resolveOptions3(options) {
|
|
13100
13314
|
const base = resolvePaths(options);
|
|
13101
|
-
const homeDir =
|
|
13102
|
-
const projectDir =
|
|
13103
|
-
const targetPath2 =
|
|
13104
|
-
const statePath2 =
|
|
13315
|
+
const homeDir = resolve8(base.homeDir);
|
|
13316
|
+
const projectDir = resolve8(base.projectDir);
|
|
13317
|
+
const targetPath2 = join20(projectDir, "AGENTS.md");
|
|
13318
|
+
const statePath2 = join20(wingmanStateRoot({ ...base, homeDir, projectDir }), "state", `plan-protocol-agents-${sha256Hex(projectDir)}.json`);
|
|
13105
13319
|
return { homeDir, projectDir, targetPath: targetPath2, statePath: statePath2, dryRun: options?.dryRun ?? false };
|
|
13106
13320
|
}
|
|
13107
13321
|
function readAgents2(targetPath2) {
|
|
13108
|
-
const bytes =
|
|
13322
|
+
const bytes = readFileSync13(targetPath2);
|
|
13109
13323
|
const text = decodeUtf8Strict2(bytes, targetPath2);
|
|
13110
13324
|
let split;
|
|
13111
13325
|
try {
|
|
@@ -13150,7 +13364,7 @@ function status2(targetPath2, state, identity, reason) {
|
|
|
13150
13364
|
...reason !== void 0 ? { reason } : {}
|
|
13151
13365
|
};
|
|
13152
13366
|
}
|
|
13153
|
-
function
|
|
13367
|
+
function result4(targetPath2, operation, changed, previousState, before, afterExists) {
|
|
13154
13368
|
return {
|
|
13155
13369
|
...status2(targetPath2, previousState),
|
|
13156
13370
|
operation,
|
|
@@ -13166,32 +13380,32 @@ function result3(targetPath2, operation, changed, previousState, before, afterEx
|
|
|
13166
13380
|
function modifiedError3(targetPath2, operation) {
|
|
13167
13381
|
return new Error(`${targetPath2}: \u53D7\u7BA1\u5757\u5DF2\u88AB\u4FEE\u6539\uFF0C\u62D2\u7EDD${operation}\u5E76\u4FDD\u7559\u7528\u6237\u5185\u5BB9`);
|
|
13168
13382
|
}
|
|
13169
|
-
function
|
|
13383
|
+
function nextBackupDir5(homeDir) {
|
|
13170
13384
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
13171
|
-
const root =
|
|
13172
|
-
let dir =
|
|
13173
|
-
for (let n = 2;
|
|
13174
|
-
dir =
|
|
13385
|
+
const root = join20(homeDir, ".wingman", "backups");
|
|
13386
|
+
let dir = join20(root, stamp);
|
|
13387
|
+
for (let n = 2; existsSync13(dir); n += 1)
|
|
13388
|
+
dir = join20(root, `${stamp}-${n}`);
|
|
13175
13389
|
return dir;
|
|
13176
13390
|
}
|
|
13177
|
-
function
|
|
13178
|
-
|
|
13391
|
+
function backupTarget4(backupDir, targetPath2, bytes) {
|
|
13392
|
+
mkdirSync9(backupDir, { recursive: true });
|
|
13179
13393
|
if (bytes !== void 0)
|
|
13180
|
-
|
|
13394
|
+
writeFileSync10(join20(backupDir, basename9(targetPath2)), bytes);
|
|
13181
13395
|
}
|
|
13182
13396
|
function readState6(statePath2, targetPath2) {
|
|
13183
|
-
if (!
|
|
13397
|
+
if (!existsSync13(statePath2))
|
|
13184
13398
|
return void 0;
|
|
13185
13399
|
try {
|
|
13186
|
-
const value = JSON.parse(
|
|
13400
|
+
const value = JSON.parse(readFileSync13(statePath2, "utf8"));
|
|
13187
13401
|
return value.version === 1 && value.targetPath === targetPath2 ? value : void 0;
|
|
13188
13402
|
} catch {
|
|
13189
13403
|
return void 0;
|
|
13190
13404
|
}
|
|
13191
13405
|
}
|
|
13192
13406
|
function writeState6(statePath2, state) {
|
|
13193
|
-
|
|
13194
|
-
|
|
13407
|
+
mkdirSync9(dirname14(statePath2), { recursive: true });
|
|
13408
|
+
writeFileSync10(statePath2, `${JSON.stringify(state, null, 2)}
|
|
13195
13409
|
`);
|
|
13196
13410
|
}
|
|
13197
13411
|
function originalBytes2(state) {
|
|
@@ -13207,6 +13421,33 @@ var init_protocol3 = __esm({
|
|
|
13207
13421
|
}
|
|
13208
13422
|
});
|
|
13209
13423
|
|
|
13424
|
+
// packages/adapter-codex/dist/protocol-user.js
|
|
13425
|
+
import { homedir as homedir12 } from "node:os";
|
|
13426
|
+
import { join as join21, resolve as resolve9 } from "node:path";
|
|
13427
|
+
function paths2(options) {
|
|
13428
|
+
const homeDir = resolve9(options?.homeDir ?? homedir12());
|
|
13429
|
+
return {
|
|
13430
|
+
homeDir,
|
|
13431
|
+
targetPath: join21(homeDir, ".codex", "AGENTS.md"),
|
|
13432
|
+
dryRun: options?.dryRun ?? false
|
|
13433
|
+
};
|
|
13434
|
+
}
|
|
13435
|
+
function protocolStatusCodexUser(options) {
|
|
13436
|
+
return { harness: "codex", ...statusPlanProtocolUser(paths2(options).targetPath) };
|
|
13437
|
+
}
|
|
13438
|
+
function installProtocolCodexUser(options) {
|
|
13439
|
+
return { harness: "codex", ...installPlanProtocolUser(paths2(options)) };
|
|
13440
|
+
}
|
|
13441
|
+
function uninstallProtocolCodexUser(options) {
|
|
13442
|
+
return { harness: "codex", ...uninstallPlanProtocolUser(paths2(options)) };
|
|
13443
|
+
}
|
|
13444
|
+
var init_protocol_user2 = __esm({
|
|
13445
|
+
"packages/adapter-codex/dist/protocol-user.js"() {
|
|
13446
|
+
"use strict";
|
|
13447
|
+
init_dist();
|
|
13448
|
+
}
|
|
13449
|
+
});
|
|
13450
|
+
|
|
13210
13451
|
// packages/adapter-codex/dist/index.js
|
|
13211
13452
|
var dist_exports3 = {};
|
|
13212
13453
|
__export(dist_exports3, {
|
|
@@ -13214,9 +13455,12 @@ __export(dist_exports3, {
|
|
|
13214
13455
|
createAdapter: () => createAdapter3,
|
|
13215
13456
|
feedbackSignals: () => feedbackSignalsCodex,
|
|
13216
13457
|
installProtocolCodex: () => installProtocolCodex,
|
|
13458
|
+
installProtocolCodexUser: () => installProtocolCodexUser,
|
|
13217
13459
|
protocolStatusCodex: () => protocolStatusCodex,
|
|
13460
|
+
protocolStatusCodexUser: () => protocolStatusCodexUser,
|
|
13218
13461
|
resolveNodeExecutable: () => resolveNodeExecutable,
|
|
13219
|
-
uninstallProtocolCodex: () => uninstallProtocolCodex
|
|
13462
|
+
uninstallProtocolCodex: () => uninstallProtocolCodex,
|
|
13463
|
+
uninstallProtocolCodexUser: () => uninstallProtocolCodexUser
|
|
13220
13464
|
});
|
|
13221
13465
|
function createAdapter3(_options) {
|
|
13222
13466
|
return {
|
|
@@ -13237,23 +13481,24 @@ var init_dist5 = __esm({
|
|
|
13237
13481
|
init_scan2();
|
|
13238
13482
|
init_hooks3();
|
|
13239
13483
|
init_protocol3();
|
|
13484
|
+
init_protocol_user2();
|
|
13240
13485
|
}
|
|
13241
13486
|
});
|
|
13242
13487
|
|
|
13243
13488
|
// apps/cli/dist/main.js
|
|
13244
13489
|
init_dist2();
|
|
13245
13490
|
init_dist();
|
|
13246
|
-
import { readFileSync as
|
|
13247
|
-
import { homedir as
|
|
13248
|
-
import { dirname as
|
|
13491
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
13492
|
+
import { homedir as homedir16 } from "node:os";
|
|
13493
|
+
import { dirname as dirname20, resolve as resolve14 } from "node:path";
|
|
13249
13494
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
13250
13495
|
|
|
13251
13496
|
// packages/fixtures/dist/index.js
|
|
13252
|
-
import { dirname as
|
|
13497
|
+
import { dirname as dirname5, join as join6 } from "node:path";
|
|
13253
13498
|
import { fileURLToPath } from "node:url";
|
|
13254
|
-
var fixturesRoot =
|
|
13499
|
+
var fixturesRoot = join6(dirname5(dirname5(fileURLToPath(import.meta.url))), "data");
|
|
13255
13500
|
function fixturePath(...segments) {
|
|
13256
|
-
return
|
|
13501
|
+
return join6(fixturesRoot, ...segments);
|
|
13257
13502
|
}
|
|
13258
13503
|
|
|
13259
13504
|
// packages/live/dist/receiver.js
|
|
@@ -13373,7 +13618,7 @@ function isHookPayload(value) {
|
|
|
13373
13618
|
}
|
|
13374
13619
|
var HOOK_BODY_LIMIT = 1024 * 1024;
|
|
13375
13620
|
function readBody(req) {
|
|
13376
|
-
return new Promise((
|
|
13621
|
+
return new Promise((resolve15, reject) => {
|
|
13377
13622
|
const chunks = [];
|
|
13378
13623
|
let size = 0;
|
|
13379
13624
|
req.on("data", (chunk) => {
|
|
@@ -13385,7 +13630,7 @@ function readBody(req) {
|
|
|
13385
13630
|
}
|
|
13386
13631
|
chunks.push(chunk);
|
|
13387
13632
|
});
|
|
13388
|
-
req.on("end", () =>
|
|
13633
|
+
req.on("end", () => resolve15(Buffer.concat(chunks).toString("utf8")));
|
|
13389
13634
|
req.on("error", reject);
|
|
13390
13635
|
});
|
|
13391
13636
|
}
|
|
@@ -13400,9 +13645,9 @@ function sendText(res, status3, body) {
|
|
|
13400
13645
|
|
|
13401
13646
|
// apps/cli/dist/license.js
|
|
13402
13647
|
import { verify } from "node:crypto";
|
|
13403
|
-
import { existsSync as
|
|
13648
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
13404
13649
|
import { homedir as homedir3 } from "node:os";
|
|
13405
|
-
import { join as
|
|
13650
|
+
import { join as join7 } from "node:path";
|
|
13406
13651
|
var OFFLINE_GRACE_DAYS = 14;
|
|
13407
13652
|
var PROD_PUBLIC_KEY_PEM = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAyU4yO0SJcflt/CV77wqVxIwCkM52CYGC6qrPGP8dMME=\n-----END PUBLIC KEY-----\n";
|
|
13408
13653
|
function checkLicense(options = {}) {
|
|
@@ -13416,7 +13661,7 @@ function licenseStatus(options = {}) {
|
|
|
13416
13661
|
const home = options.homeDir ?? homedir3();
|
|
13417
13662
|
let raw;
|
|
13418
13663
|
try {
|
|
13419
|
-
raw =
|
|
13664
|
+
raw = readFileSync3(join7(home, ".wingman", "license.json"), "utf8");
|
|
13420
13665
|
} catch {
|
|
13421
13666
|
return { state: "none", detail: "\u672A\u5B89\u88C5 license(anatomy \u4E0E\u5B9E\u51B5\u514D\u8D39\u53EF\u7528;\u5199\u52A8\u4F5C\u9700\u8BA2\u9605)" };
|
|
13422
13667
|
}
|
|
@@ -13483,7 +13728,7 @@ function verifyEntitlement(raw, now, publicKeyPem) {
|
|
|
13483
13728
|
function nextLicenseBackupPath(licensePath, now) {
|
|
13484
13729
|
const base = `${licensePath}.bak-${now.toISOString().replaceAll(":", "-")}`;
|
|
13485
13730
|
let candidate = base;
|
|
13486
|
-
for (let index = 2;
|
|
13731
|
+
for (let index = 2; existsSync4(candidate); index++)
|
|
13487
13732
|
candidate = `${base}-${index}`;
|
|
13488
13733
|
return candidate;
|
|
13489
13734
|
}
|
|
@@ -13504,13 +13749,13 @@ function installLicense(raw, options = {}) {
|
|
|
13504
13749
|
return { ok: false, error: status3.detail };
|
|
13505
13750
|
}
|
|
13506
13751
|
}
|
|
13507
|
-
const dir =
|
|
13508
|
-
const licensePath =
|
|
13509
|
-
const tmpPath =
|
|
13752
|
+
const dir = join7(options.homeDir ?? homedir3(), ".wingman");
|
|
13753
|
+
const licensePath = join7(dir, "license.json");
|
|
13754
|
+
const tmpPath = join7(dir, `.license.json.tmp-${process.pid}`);
|
|
13510
13755
|
try {
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
if (
|
|
13756
|
+
mkdirSync3(dir, { recursive: true });
|
|
13757
|
+
writeFileSync3(tmpPath, raw);
|
|
13758
|
+
if (existsSync4(licensePath)) {
|
|
13514
13759
|
renameSync(licensePath, nextLicenseBackupPath(licensePath, options.now ?? /* @__PURE__ */ new Date()));
|
|
13515
13760
|
}
|
|
13516
13761
|
renameSync(tmpPath, licensePath);
|
|
@@ -13522,17 +13767,17 @@ function installLicense(raw, options = {}) {
|
|
|
13522
13767
|
}
|
|
13523
13768
|
|
|
13524
13769
|
// apps/cli/dist/license-refresh.js
|
|
13525
|
-
import { copyFileSync, readFileSync as
|
|
13770
|
+
import { copyFileSync, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
13526
13771
|
import { homedir as homedir4 } from "node:os";
|
|
13527
|
-
import { dirname as
|
|
13772
|
+
import { dirname as dirname6, join as join8 } from "node:path";
|
|
13528
13773
|
var DEFAULT_LICENSE_SERVER = "https://api.getwingman.dev";
|
|
13529
13774
|
async function refreshLicense(options = {}) {
|
|
13530
13775
|
const home = options.homeDir ?? homedir4();
|
|
13531
13776
|
const baseUrl = options.baseUrl ?? process.env.WINGMAN_LICENSE_SERVER ?? DEFAULT_LICENSE_SERVER;
|
|
13532
|
-
const licensePath =
|
|
13777
|
+
const licensePath = join8(home, ".wingman", "license.json");
|
|
13533
13778
|
let raw;
|
|
13534
13779
|
try {
|
|
13535
|
-
raw =
|
|
13780
|
+
raw = readFileSync4(licensePath, "utf8");
|
|
13536
13781
|
} catch {
|
|
13537
13782
|
return {
|
|
13538
13783
|
ok: false,
|
|
@@ -13602,7 +13847,7 @@ async function refreshLicense(options = {}) {
|
|
|
13602
13847
|
}
|
|
13603
13848
|
}
|
|
13604
13849
|
try {
|
|
13605
|
-
if (
|
|
13850
|
+
if (readFileSync4(licensePath, "utf8") !== raw) {
|
|
13606
13851
|
return {
|
|
13607
13852
|
ok: false,
|
|
13608
13853
|
message: "\u5237\u65B0\u671F\u95F4\u672C\u673A\u6388\u6743\u5DF2\u88AB\u66F4\u6362;\u5DF2\u4FDD\u7559\u8F83\u65B0\u7684\u6587\u4EF6,\u8BF7\u518D\u70B9\u4E00\u6B21\u5237\u65B0",
|
|
@@ -13616,9 +13861,9 @@ async function refreshLicense(options = {}) {
|
|
|
13616
13861
|
reason: "changed"
|
|
13617
13862
|
};
|
|
13618
13863
|
}
|
|
13619
|
-
const tmpPath =
|
|
13864
|
+
const tmpPath = join8(dirname6(licensePath), `.license.json.tmp-${process.pid}`);
|
|
13620
13865
|
try {
|
|
13621
|
-
|
|
13866
|
+
writeFileSync4(tmpPath, next);
|
|
13622
13867
|
copyFileSync(licensePath, nextLicenseBackupPath(licensePath, options.now ?? /* @__PURE__ */ new Date()));
|
|
13623
13868
|
renameSync2(tmpPath, licensePath);
|
|
13624
13869
|
} catch (error) {
|
|
@@ -13646,7 +13891,7 @@ init_dist5();
|
|
|
13646
13891
|
init_dist2();
|
|
13647
13892
|
init_dist();
|
|
13648
13893
|
import { readdir as readdir2 } from "node:fs/promises";
|
|
13649
|
-
import { isAbsolute as isAbsolute6, join as
|
|
13894
|
+
import { isAbsolute as isAbsolute6, join as join25, resolve as resolve11 } from "node:path";
|
|
13650
13895
|
|
|
13651
13896
|
// packages/narrative/dist/attribute.js
|
|
13652
13897
|
function extractSteps(lines2) {
|
|
@@ -13671,13 +13916,13 @@ function extractSteps(lines2) {
|
|
|
13671
13916
|
byToolUseId.set(block.id, step);
|
|
13672
13917
|
}
|
|
13673
13918
|
} else if (line.kind === "user") {
|
|
13674
|
-
for (const
|
|
13675
|
-
const step = byToolUseId.get(
|
|
13919
|
+
for (const result5 of line.toolResults) {
|
|
13920
|
+
const step = byToolUseId.get(result5.toolUseId);
|
|
13676
13921
|
if (step === void 0)
|
|
13677
13922
|
continue;
|
|
13678
13923
|
if (line.timestamp !== void 0)
|
|
13679
13924
|
step.endTs = line.timestamp;
|
|
13680
|
-
if (
|
|
13925
|
+
if (result5.isError)
|
|
13681
13926
|
step.isError = true;
|
|
13682
13927
|
}
|
|
13683
13928
|
}
|
|
@@ -13849,17 +14094,17 @@ function parseResponseItem(payload, timestamp) {
|
|
|
13849
14094
|
return call;
|
|
13850
14095
|
}
|
|
13851
14096
|
if (payload !== void 0 && (payloadType === "function_call_output" || payloadType === "custom_tool_call_output")) {
|
|
13852
|
-
const
|
|
13853
|
-
assignString(
|
|
13854
|
-
assignString(
|
|
13855
|
-
assignString(
|
|
13856
|
-
assignString(
|
|
14097
|
+
const result5 = { kind: "tool_result", resultType: payloadType };
|
|
14098
|
+
assignString(result5, "timestamp", timestamp);
|
|
14099
|
+
assignString(result5, "callId", optionalString(payload.call_id));
|
|
14100
|
+
assignString(result5, "itemId", optionalString(payload.id));
|
|
14101
|
+
assignString(result5, "turnId", extractTurnId(payload));
|
|
13857
14102
|
if (payload.output !== void 0) {
|
|
13858
|
-
|
|
14103
|
+
result5.output = payload.output;
|
|
13859
14104
|
if (codexToolResultIsError(payload.output))
|
|
13860
|
-
|
|
14105
|
+
result5.isError = true;
|
|
13861
14106
|
}
|
|
13862
|
-
return
|
|
14107
|
+
return result5;
|
|
13863
14108
|
}
|
|
13864
14109
|
return otherLine("response_item", payload, timestamp);
|
|
13865
14110
|
}
|
|
@@ -14041,13 +14286,13 @@ function parseUser(raw, common) {
|
|
|
14041
14286
|
if (!isRecord3(block))
|
|
14042
14287
|
continue;
|
|
14043
14288
|
if (block.type === "tool_result" && typeof block.tool_use_id === "string") {
|
|
14044
|
-
const
|
|
14289
|
+
const result5 = {
|
|
14045
14290
|
toolUseId: block.tool_use_id,
|
|
14046
14291
|
// 实测:成功结果常无 is_error 字段;仅显式 true 视为失败
|
|
14047
14292
|
isError: block.is_error === true,
|
|
14048
14293
|
content: block.content
|
|
14049
14294
|
};
|
|
14050
|
-
line.toolResults.push(
|
|
14295
|
+
line.toolResults.push(result5);
|
|
14051
14296
|
} else if (block.type === "text" && typeof block.text === "string") {
|
|
14052
14297
|
texts.push(block.text);
|
|
14053
14298
|
}
|
|
@@ -14570,11 +14815,11 @@ function buildTaskCreateResultIndex(lines2) {
|
|
|
14570
14815
|
for (const line of lines2) {
|
|
14571
14816
|
if (line.kind !== "user")
|
|
14572
14817
|
continue;
|
|
14573
|
-
const
|
|
14574
|
-
if (!isRecord3(
|
|
14818
|
+
const result5 = line.toolUseResult;
|
|
14819
|
+
if (!isRecord3(result5) || !isRecord3(result5.task) || typeof result5.task.id !== "string")
|
|
14575
14820
|
continue;
|
|
14576
14821
|
for (const toolResult of line.toolResults)
|
|
14577
|
-
index.set(toolResult.toolUseId,
|
|
14822
|
+
index.set(toolResult.toolUseId, result5.task.id);
|
|
14578
14823
|
}
|
|
14579
14824
|
return index;
|
|
14580
14825
|
}
|
|
@@ -14708,7 +14953,7 @@ function turnUsage(line) {
|
|
|
14708
14953
|
if (inputTokens === void 0 || cacheCreationInputTokens === void 0 || cacheReadInputTokens === void 0 || outputTokens === void 0) {
|
|
14709
14954
|
return void 0;
|
|
14710
14955
|
}
|
|
14711
|
-
const
|
|
14956
|
+
const result5 = {
|
|
14712
14957
|
inputTokens,
|
|
14713
14958
|
cacheCreationInputTokens,
|
|
14714
14959
|
cacheReadInputTokens,
|
|
@@ -14723,11 +14968,11 @@ function turnUsage(line) {
|
|
|
14723
14968
|
const fiveMinute = finiteNumber(breakdown.ephemeral_5m_input_tokens);
|
|
14724
14969
|
const oneHour = finiteNumber(breakdown.ephemeral_1h_input_tokens);
|
|
14725
14970
|
if (fiveMinute !== void 0)
|
|
14726
|
-
|
|
14971
|
+
result5.cacheCreation5mTokens = fiveMinute;
|
|
14727
14972
|
if (oneHour !== void 0)
|
|
14728
|
-
|
|
14973
|
+
result5.cacheCreation1hTokens = oneHour;
|
|
14729
14974
|
}
|
|
14730
|
-
return
|
|
14975
|
+
return result5;
|
|
14731
14976
|
}
|
|
14732
14977
|
function finiteNumber(value) {
|
|
14733
14978
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
@@ -15101,9 +15346,9 @@ function fromTool(harness, name, input, source, at) {
|
|
|
15101
15346
|
return [];
|
|
15102
15347
|
if (harness === "codex" && name === "exec") {
|
|
15103
15348
|
const inputText = toolText(input, ["input"]);
|
|
15104
|
-
const
|
|
15105
|
-
if (
|
|
15106
|
-
return
|
|
15349
|
+
const paths3 = codexExecPatchPaths(inputText);
|
|
15350
|
+
if (paths3.length > 0) {
|
|
15351
|
+
return paths3.map((path) => fileObservation(path, "codex apply_patch via exec", source, false, at));
|
|
15107
15352
|
}
|
|
15108
15353
|
}
|
|
15109
15354
|
if (name === "Bash" || name === "exec") {
|
|
@@ -15145,13 +15390,13 @@ function fileObservation(path, method, source, wholeFile, at) {
|
|
|
15145
15390
|
function patchPaths(patch) {
|
|
15146
15391
|
if (patch === void 0)
|
|
15147
15392
|
return [];
|
|
15148
|
-
const
|
|
15393
|
+
const paths3 = [];
|
|
15149
15394
|
for (const line of patch.split("\n")) {
|
|
15150
15395
|
const match = /^\*\*\* (?:Update|Add) File: (.+?)\s*$/u.exec(line);
|
|
15151
15396
|
if (match?.[1] !== void 0 && isPlanPath(match[1]))
|
|
15152
|
-
|
|
15397
|
+
paths3.push(match[1]);
|
|
15153
15398
|
}
|
|
15154
|
-
return
|
|
15399
|
+
return paths3;
|
|
15155
15400
|
}
|
|
15156
15401
|
function codexExecPatchPaths(input) {
|
|
15157
15402
|
if (input === void 0 || !input.includes("*** Begin Patch"))
|
|
@@ -15212,22 +15457,29 @@ function isRecord5(value) {
|
|
|
15212
15457
|
|
|
15213
15458
|
// apps/cli/dist/project-index.js
|
|
15214
15459
|
import { lstat, readFile as readFile3, realpath, stat as stat3 } from "node:fs/promises";
|
|
15215
|
-
import { dirname as
|
|
15460
|
+
import { dirname as dirname15, isAbsolute as isAbsolute4, join as join22, relative as relative3, resolve as resolve10 } from "node:path";
|
|
15216
15461
|
var PROJECT_ROOT_MAX_DIRECTORIES = 8;
|
|
15217
15462
|
var PROJECT_PLAN_POLL_MS = 2e3;
|
|
15218
15463
|
async function resolveProjectRoot(cwd, options) {
|
|
15219
|
-
const root =
|
|
15220
|
-
const homeDir =
|
|
15221
|
-
const boundaryDir = options.boundaryDir === void 0 ? void 0 :
|
|
15464
|
+
const root = resolve10(cwd);
|
|
15465
|
+
const homeDir = resolve10(options.homeDir);
|
|
15466
|
+
const boundaryDir = options.boundaryDir === void 0 ? void 0 : resolve10(options.boundaryDir);
|
|
15222
15467
|
const [rootIdentity, homeIdentity, boundaryIdentity] = await Promise.all([
|
|
15223
15468
|
pathIdentity(root),
|
|
15224
15469
|
pathIdentity(homeDir),
|
|
15225
15470
|
boundaryDir === void 0 ? void 0 : pathIdentity(boundaryDir)
|
|
15226
15471
|
]);
|
|
15227
|
-
const wingmanHomeIdentity = await pathIdentity(
|
|
15228
|
-
const planPathIdentity = await pathIdentity(
|
|
15472
|
+
const wingmanHomeIdentity = await pathIdentity(join22(homeIdentity, ".wingman"));
|
|
15473
|
+
const planPathIdentity = await pathIdentity(join22(rootIdentity, ".wingman", "plan.md"));
|
|
15229
15474
|
if (rootIdentity === homeIdentity || rootIdentity === wingmanHomeIdentity || boundaryIdentity !== void 0 && !isWithin(boundaryIdentity, rootIdentity)) {
|
|
15230
|
-
return {
|
|
15475
|
+
return {
|
|
15476
|
+
root,
|
|
15477
|
+
rootIdentity,
|
|
15478
|
+
planPathIdentity,
|
|
15479
|
+
lookedUp: [],
|
|
15480
|
+
higherPlanPaths: [],
|
|
15481
|
+
...rootIdentity === homeIdentity ? { isHome: true } : {}
|
|
15482
|
+
};
|
|
15231
15483
|
}
|
|
15232
15484
|
const lookedUp = [];
|
|
15233
15485
|
const found = [];
|
|
@@ -15239,7 +15491,7 @@ async function resolveProjectRoot(cwd, options) {
|
|
|
15239
15491
|
break;
|
|
15240
15492
|
if (boundaryIdentity !== void 0 && !isWithin(boundaryIdentity, currentIdentity))
|
|
15241
15493
|
break;
|
|
15242
|
-
const planPath =
|
|
15494
|
+
const planPath = join22(current, ".wingman", "plan.md");
|
|
15243
15495
|
lookedUp.push(planPath);
|
|
15244
15496
|
try {
|
|
15245
15497
|
await lstat(planPath);
|
|
@@ -15251,7 +15503,7 @@ async function resolveProjectRoot(cwd, options) {
|
|
|
15251
15503
|
});
|
|
15252
15504
|
} catch {
|
|
15253
15505
|
}
|
|
15254
|
-
const parent =
|
|
15506
|
+
const parent = dirname15(current);
|
|
15255
15507
|
if (parent === current)
|
|
15256
15508
|
break;
|
|
15257
15509
|
current = parent;
|
|
@@ -15329,7 +15581,7 @@ function watchProjectPlan(planPath, options) {
|
|
|
15329
15581
|
};
|
|
15330
15582
|
}
|
|
15331
15583
|
async function pathIdentity(path) {
|
|
15332
|
-
const resolved =
|
|
15584
|
+
const resolved = resolve10(path);
|
|
15333
15585
|
try {
|
|
15334
15586
|
return normalizedPath(await realpath(resolved));
|
|
15335
15587
|
} catch {
|
|
@@ -15344,7 +15596,7 @@ async function pathsReferToSameLocation(left, right) {
|
|
|
15344
15596
|
return relative3(leftIdentity, rightIdentity) === "";
|
|
15345
15597
|
}
|
|
15346
15598
|
function normalizedPath(path) {
|
|
15347
|
-
const resolved =
|
|
15599
|
+
const resolved = resolve10(path);
|
|
15348
15600
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
15349
15601
|
}
|
|
15350
15602
|
function isWithin(parent, child) {
|
|
@@ -15354,17 +15606,17 @@ function isWithin(parent, child) {
|
|
|
15354
15606
|
|
|
15355
15607
|
// apps/cli/dist/project-roots.js
|
|
15356
15608
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
15357
|
-
import { closeSync, mkdirSync as
|
|
15358
|
-
import { dirname as
|
|
15609
|
+
import { closeSync, mkdirSync as mkdirSync10, openSync, readFileSync as readFileSync14, renameSync as renameSync3, rmSync as rmSync8, statSync as statSync5, writeFileSync as writeFileSync11 } from "node:fs";
|
|
15610
|
+
import { dirname as dirname16, isAbsolute as isAbsolute5, join as join23 } from "node:path";
|
|
15359
15611
|
var PROJECT_ROOTS_MAX_ENTRIES = 200;
|
|
15360
15612
|
function projectRootsPath(homeDir) {
|
|
15361
|
-
return
|
|
15613
|
+
return join23(homeDir, ".wingman", "state", "projects.json");
|
|
15362
15614
|
}
|
|
15363
15615
|
function readProjectRoots(homeDir) {
|
|
15364
15616
|
const path = projectRootsPath(homeDir);
|
|
15365
15617
|
let raw;
|
|
15366
15618
|
try {
|
|
15367
|
-
raw =
|
|
15619
|
+
raw = readFileSync14(path, "utf8");
|
|
15368
15620
|
} catch (error) {
|
|
15369
15621
|
if (isErrno(error, "ENOENT"))
|
|
15370
15622
|
return { version: 1, roots: {} };
|
|
@@ -15404,7 +15656,7 @@ function pruneProjectRoots(homeDir) {
|
|
|
15404
15656
|
return current;
|
|
15405
15657
|
const roots = Object.fromEntries(Object.entries(current.roots).filter(([, entry]) => {
|
|
15406
15658
|
try {
|
|
15407
|
-
statSync5(
|
|
15659
|
+
statSync5(join23(entry.root, ".wingman", "plan.md"));
|
|
15408
15660
|
return true;
|
|
15409
15661
|
} catch (error) {
|
|
15410
15662
|
return !isErrno(error, "ENOENT") && !isErrno(error, "ENOTDIR");
|
|
@@ -15428,12 +15680,12 @@ function limitRoots(roots) {
|
|
|
15428
15680
|
}
|
|
15429
15681
|
function writeProjectRoots(homeDir, state) {
|
|
15430
15682
|
const path = projectRootsPath(homeDir);
|
|
15431
|
-
const tempPath =
|
|
15683
|
+
const tempPath = join23(dirname16(path), `.projects-${randomBytes2(8).toString("hex")}.tmp`);
|
|
15432
15684
|
let fd;
|
|
15433
15685
|
try {
|
|
15434
|
-
|
|
15686
|
+
mkdirSync10(dirname16(path), { recursive: true, mode: 448 });
|
|
15435
15687
|
fd = openSync(tempPath, "wx", 384);
|
|
15436
|
-
|
|
15688
|
+
writeFileSync11(fd, `${JSON.stringify(state)}
|
|
15437
15689
|
`, "utf8");
|
|
15438
15690
|
closeSync(fd);
|
|
15439
15691
|
fd = void 0;
|
|
@@ -15446,7 +15698,7 @@ function writeProjectRoots(homeDir, state) {
|
|
|
15446
15698
|
}
|
|
15447
15699
|
}
|
|
15448
15700
|
try {
|
|
15449
|
-
|
|
15701
|
+
rmSync8(tempPath, { force: true });
|
|
15450
15702
|
} catch {
|
|
15451
15703
|
}
|
|
15452
15704
|
throw error;
|
|
@@ -15475,16 +15727,16 @@ function isErrno(error, code) {
|
|
|
15475
15727
|
|
|
15476
15728
|
// apps/cli/dist/task-overlay.js
|
|
15477
15729
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
15478
|
-
import { closeSync as closeSync2, mkdirSync as
|
|
15479
|
-
import { dirname as
|
|
15730
|
+
import { closeSync as closeSync2, mkdirSync as mkdirSync11, openSync as openSync2, readFileSync as readFileSync15, renameSync as renameSync4, rmSync as rmSync9, writeFileSync as writeFileSync12 } from "node:fs";
|
|
15731
|
+
import { dirname as dirname17, join as join24 } from "node:path";
|
|
15480
15732
|
function taskOverlayPath(homeDir) {
|
|
15481
|
-
return
|
|
15733
|
+
return join24(homeDir, ".wingman", "state", "task-overlay.json");
|
|
15482
15734
|
}
|
|
15483
15735
|
function readTaskOverlay(homeDir) {
|
|
15484
15736
|
const path = taskOverlayPath(homeDir);
|
|
15485
15737
|
let raw;
|
|
15486
15738
|
try {
|
|
15487
|
-
raw =
|
|
15739
|
+
raw = readFileSync15(path, "utf8");
|
|
15488
15740
|
} catch (error) {
|
|
15489
15741
|
if (isErrno2(error, "ENOENT"))
|
|
15490
15742
|
return { version: 1, entries: {} };
|
|
@@ -15536,12 +15788,12 @@ function patchTaskOverlay(homeDir, key, patch, now) {
|
|
|
15536
15788
|
}
|
|
15537
15789
|
function writeTaskOverlay(homeDir, overlay) {
|
|
15538
15790
|
const path = taskOverlayPath(homeDir);
|
|
15539
|
-
const tempPath =
|
|
15791
|
+
const tempPath = join24(dirname17(path), `.task-overlay-${randomBytes3(8).toString("hex")}.tmp`);
|
|
15540
15792
|
let fd;
|
|
15541
15793
|
try {
|
|
15542
|
-
|
|
15794
|
+
mkdirSync11(dirname17(path), { recursive: true, mode: 448 });
|
|
15543
15795
|
fd = openSync2(tempPath, "wx", 384);
|
|
15544
|
-
|
|
15796
|
+
writeFileSync12(fd, `${JSON.stringify(overlay)}
|
|
15545
15797
|
`, "utf8");
|
|
15546
15798
|
closeSync2(fd);
|
|
15547
15799
|
fd = void 0;
|
|
@@ -15554,7 +15806,7 @@ function writeTaskOverlay(homeDir, overlay) {
|
|
|
15554
15806
|
}
|
|
15555
15807
|
}
|
|
15556
15808
|
try {
|
|
15557
|
-
|
|
15809
|
+
rmSync9(tempPath, { force: true });
|
|
15558
15810
|
} catch {
|
|
15559
15811
|
}
|
|
15560
15812
|
throw error;
|
|
@@ -15587,7 +15839,7 @@ function errorMessage(error) {
|
|
|
15587
15839
|
}
|
|
15588
15840
|
|
|
15589
15841
|
// apps/cli/dist/version.js
|
|
15590
|
-
import { readFileSync as
|
|
15842
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
15591
15843
|
function resolveWingmanVersion({ defined, moduleUrl = import.meta.url, readPackage }) {
|
|
15592
15844
|
if (typeof defined === "string" && defined.trim() !== "")
|
|
15593
15845
|
return defined;
|
|
@@ -15606,10 +15858,10 @@ function resolveWingmanVersion({ defined, moduleUrl = import.meta.url, readPacka
|
|
|
15606
15858
|
return void 0;
|
|
15607
15859
|
}
|
|
15608
15860
|
function wingmanVersion() {
|
|
15609
|
-
const defined = false ? void 0 : "0.8.
|
|
15861
|
+
const defined = false ? void 0 : "0.8.1";
|
|
15610
15862
|
return resolveWingmanVersion({
|
|
15611
15863
|
defined,
|
|
15612
|
-
readPackage: (url) => JSON.parse(
|
|
15864
|
+
readPackage: (url) => JSON.parse(readFileSync16(url, "utf8"))
|
|
15613
15865
|
});
|
|
15614
15866
|
}
|
|
15615
15867
|
|
|
@@ -15692,6 +15944,9 @@ function createNarrativeService(options = {}) {
|
|
|
15692
15944
|
generation: 0,
|
|
15693
15945
|
lines: [],
|
|
15694
15946
|
codexLines: [],
|
|
15947
|
+
instructionSeq: 0,
|
|
15948
|
+
sessionPlanSeq: 0,
|
|
15949
|
+
hookInstructions: [],
|
|
15695
15950
|
pendingPlanWrites: [],
|
|
15696
15951
|
confirmedPlanWrites: [],
|
|
15697
15952
|
nonPlanToolSteps: 0,
|
|
@@ -15725,6 +15980,8 @@ function createNarrativeService(options = {}) {
|
|
|
15725
15980
|
if (closed || session.cwd !== cwd)
|
|
15726
15981
|
return;
|
|
15727
15982
|
session.projectResolution = resolution;
|
|
15983
|
+
if (resolution.isHome)
|
|
15984
|
+
session.label = "\u65E0\u9879\u76EE\u76EE\u5F55(\u5BB6\u76EE\u5F55)";
|
|
15728
15985
|
seenProjectRoots.add(resolution.rootIdentity);
|
|
15729
15986
|
rememberResolution(resolution);
|
|
15730
15987
|
watchResolution(resolution);
|
|
@@ -15778,7 +16035,7 @@ function createNarrativeService(options = {}) {
|
|
|
15778
16035
|
function watchResolution(resolution) {
|
|
15779
16036
|
if (resolution.lookedUp.length === 0)
|
|
15780
16037
|
return;
|
|
15781
|
-
const planPath = resolution.planPath ??
|
|
16038
|
+
const planPath = resolution.planPath ?? join25(resolution.root, ".wingman", "plan.md");
|
|
15782
16039
|
const planPathIdentity = resolution.planPathIdentity;
|
|
15783
16040
|
if (projectWatchers.has(planPathIdentity))
|
|
15784
16041
|
return;
|
|
@@ -15867,7 +16124,7 @@ function createNarrativeService(options = {}) {
|
|
|
15867
16124
|
for (const session of sessions.values()) {
|
|
15868
16125
|
const resolution = session.projectResolution;
|
|
15869
16126
|
if (resolution?.planPathIdentity === planPathIdentity) {
|
|
15870
|
-
const planPath = resolution.planPath ??
|
|
16127
|
+
const planPath = resolution.planPath ?? join25(resolution.root, ".wingman", "plan.md");
|
|
15871
16128
|
void applyPendingPlanWrites(session, planPath, planPathIdentity).then(() => {
|
|
15872
16129
|
session.dirty = true;
|
|
15873
16130
|
notify(harness);
|
|
@@ -15912,7 +16169,7 @@ function createNarrativeService(options = {}) {
|
|
|
15912
16169
|
}
|
|
15913
16170
|
const resolution = session.projectResolution;
|
|
15914
16171
|
if (resolution !== void 0) {
|
|
15915
|
-
const planPath = resolution.planPath ??
|
|
16172
|
+
const planPath = resolution.planPath ?? join25(resolution.root, ".wingman", "plan.md");
|
|
15916
16173
|
void applyPendingPlanWrites(session, planPath, resolution.planPathIdentity).then(() => {
|
|
15917
16174
|
session.dirty = true;
|
|
15918
16175
|
notify(harness);
|
|
@@ -15942,12 +16199,12 @@ function createNarrativeService(options = {}) {
|
|
|
15942
16199
|
at: observation.at ?? versions.current.info.mtime,
|
|
15943
16200
|
nonPlanStepsBefore: pending.nonPlanStepsBefore
|
|
15944
16201
|
});
|
|
15945
|
-
const
|
|
15946
|
-
if ("attachedTo" in
|
|
15947
|
-
session.planAttachment =
|
|
16202
|
+
const result5 = attributePlanWrite(before, after, observation);
|
|
16203
|
+
if ("attachedTo" in result5) {
|
|
16204
|
+
session.planAttachment = result5;
|
|
15948
16205
|
session.planUnattachedReason = void 0;
|
|
15949
16206
|
} else {
|
|
15950
|
-
session.planUnattachedReason =
|
|
16207
|
+
session.planUnattachedReason = result5.reason;
|
|
15951
16208
|
}
|
|
15952
16209
|
}
|
|
15953
16210
|
session.pendingPlanWrites = remaining;
|
|
@@ -16002,8 +16259,13 @@ function createNarrativeService(options = {}) {
|
|
|
16002
16259
|
session.lines = [];
|
|
16003
16260
|
session.codexLines = [];
|
|
16004
16261
|
session.hookIntervals = [];
|
|
16005
|
-
session.
|
|
16006
|
-
|
|
16262
|
+
if (session.transcriptPath !== void 0) {
|
|
16263
|
+
session.hookPrompt = void 0;
|
|
16264
|
+
session.hookPromptAt = void 0;
|
|
16265
|
+
session.hookInstructions = [];
|
|
16266
|
+
}
|
|
16267
|
+
session.instructionSeq = 0;
|
|
16268
|
+
session.sessionPlanSeq = 0;
|
|
16007
16269
|
session.mockNote = void 0;
|
|
16008
16270
|
session.transcriptPath = path;
|
|
16009
16271
|
session.dirty = true;
|
|
@@ -16040,7 +16302,7 @@ function createNarrativeService(options = {}) {
|
|
|
16040
16302
|
const sessionDir = transcriptPath.replace(/\.jsonl$/, "");
|
|
16041
16303
|
if (sessionDir === transcriptPath)
|
|
16042
16304
|
return;
|
|
16043
|
-
const subagentsDir =
|
|
16305
|
+
const subagentsDir = join25(sessionDir, "subagents");
|
|
16044
16306
|
const generation = session.generation;
|
|
16045
16307
|
const poll = async () => {
|
|
16046
16308
|
try {
|
|
@@ -16050,7 +16312,7 @@ function createNarrativeService(options = {}) {
|
|
|
16050
16312
|
}
|
|
16051
16313
|
for (const entry of entries) {
|
|
16052
16314
|
if (/^agent-.*\.jsonl$/.test(entry)) {
|
|
16053
|
-
startFollowing(harness, session,
|
|
16315
|
+
startFollowing(harness, session, join25(subagentsDir, entry), generation);
|
|
16054
16316
|
}
|
|
16055
16317
|
}
|
|
16056
16318
|
} catch {
|
|
@@ -16073,7 +16335,7 @@ function createNarrativeService(options = {}) {
|
|
|
16073
16335
|
if (cwd !== void 0) {
|
|
16074
16336
|
anchorCwd(event.harness, session, cwd);
|
|
16075
16337
|
const base = pathBasename(cwd);
|
|
16076
|
-
if (base !== "")
|
|
16338
|
+
if (base !== "" && !session.projectResolution?.isHome)
|
|
16077
16339
|
session.label = base;
|
|
16078
16340
|
}
|
|
16079
16341
|
recordToolObservations(event.harness, session, extractToolObservations(event.harness, [{ ...payload, received_at: event.received_at }]));
|
|
@@ -16086,11 +16348,17 @@ function createNarrativeService(options = {}) {
|
|
|
16086
16348
|
}
|
|
16087
16349
|
}
|
|
16088
16350
|
}
|
|
16089
|
-
if (name === "UserPromptSubmit"
|
|
16090
|
-
const prompt = payload.prompt.trim();
|
|
16091
|
-
if (prompt !== "" && !isHarnessSystemNotice(prompt)) {
|
|
16092
|
-
session.
|
|
16093
|
-
|
|
16351
|
+
if (name === "UserPromptSubmit") {
|
|
16352
|
+
const prompt = typeof payload.prompt === "string" ? payload.prompt.trim() : void 0;
|
|
16353
|
+
if (prompt === void 0 || prompt !== "" && !isHarnessSystemNotice(prompt)) {
|
|
16354
|
+
session.hookInstructions.push({
|
|
16355
|
+
at: event.received_at,
|
|
16356
|
+
...prompt === void 0 ? {} : { text: prompt }
|
|
16357
|
+
});
|
|
16358
|
+
if (prompt !== void 0) {
|
|
16359
|
+
session.hookPrompt = truncate(prompt, DETAIL_LIMIT);
|
|
16360
|
+
session.hookPromptAt = event.received_at;
|
|
16361
|
+
}
|
|
16094
16362
|
}
|
|
16095
16363
|
}
|
|
16096
16364
|
if (name === "SubagentStart") {
|
|
@@ -16176,7 +16444,7 @@ function createNarrativeService(options = {}) {
|
|
|
16176
16444
|
if (cwd !== void 0) {
|
|
16177
16445
|
anchorCwd(harness, session2, cwd);
|
|
16178
16446
|
const base = pathBasename(cwd);
|
|
16179
|
-
if (base !== "")
|
|
16447
|
+
if (base !== "" && !session2.projectResolution?.isHome)
|
|
16180
16448
|
session2.label = base;
|
|
16181
16449
|
}
|
|
16182
16450
|
session2.dirty = true;
|
|
@@ -16203,7 +16471,7 @@ function createNarrativeService(options = {}) {
|
|
|
16203
16471
|
if (typeof cwd === "string") {
|
|
16204
16472
|
anchorCwd(harness, session, cwd);
|
|
16205
16473
|
const base = pathBasename(cwd);
|
|
16206
|
-
if (base !== "")
|
|
16474
|
+
if (base !== "" && !session.projectResolution?.isHome)
|
|
16207
16475
|
session.label = base;
|
|
16208
16476
|
break;
|
|
16209
16477
|
}
|
|
@@ -16345,7 +16613,7 @@ function createNarrativeService(options = {}) {
|
|
|
16345
16613
|
for (const session of sessions.values()) {
|
|
16346
16614
|
if (session.cwd === void 0)
|
|
16347
16615
|
continue;
|
|
16348
|
-
const rootIdentity = session.projectResolution?.rootIdentity ??
|
|
16616
|
+
const rootIdentity = session.projectResolution?.rootIdentity ?? resolve11(session.cwd);
|
|
16349
16617
|
const group = grouped.get(rootIdentity);
|
|
16350
16618
|
if (group === void 0) {
|
|
16351
16619
|
grouped.set(rootIdentity, {
|
|
@@ -16365,8 +16633,8 @@ function createNarrativeService(options = {}) {
|
|
|
16365
16633
|
for (const [rootIdentity, group] of grouped) {
|
|
16366
16634
|
const { members } = group;
|
|
16367
16635
|
const resolution = members.find((member) => member.session.projectResolution !== void 0)?.session.projectResolution ?? group.resolution;
|
|
16368
|
-
const root = resolution?.root ??
|
|
16369
|
-
const planPath = resolution?.planPath ??
|
|
16636
|
+
const root = resolution?.root ?? resolve11(members[0]?.session.cwd ?? "");
|
|
16637
|
+
const planPath = resolution?.planPath ?? join25(root, ".wingman", "plan.md");
|
|
16370
16638
|
const runtime = projectFiles.get(resolution?.planPathIdentity ?? planPath);
|
|
16371
16639
|
const parsed = runtime?.missing === true ? void 0 : runtime?.parsed;
|
|
16372
16640
|
const planMtime = parsed?.availability === "available" ? runtime?.current?.info.mtime : void 0;
|
|
@@ -16384,12 +16652,13 @@ function createNarrativeService(options = {}) {
|
|
|
16384
16652
|
const verification = state?.taskWorkflow?.verification;
|
|
16385
16653
|
const attachedTitle = session.planAttachment?.attachedTo.split(" > ").at(-1);
|
|
16386
16654
|
const instructionTitle = state?.taskWorkflow?.latestInstruction?.text;
|
|
16655
|
+
const planInstruction = state?.taskWorkflow?.plan.availability === "available" ? session.sessionPlanInstruction : void 0;
|
|
16387
16656
|
return {
|
|
16388
16657
|
harness,
|
|
16389
16658
|
id: session.id,
|
|
16390
16659
|
label,
|
|
16391
16660
|
ended: info?.ended ?? false,
|
|
16392
|
-
title: attachedTitle !== void 0 ? { text: attachedTitle, source: "plan.md \u6B65\u9AA4" } : instructionTitle !== void 0 ? { text: truncate(instructionTitle, DETAIL_LIMIT), source: "\u6700\u65B0\u6307\u4EE4" } : { text: label, source: "\u5DE5\u4F5C\u76EE\u5F55" },
|
|
16661
|
+
title: attachedTitle !== void 0 ? { text: attachedTitle, source: "plan.md \u6B65\u9AA4" } : planInstruction !== void 0 ? { text: truncate(planInstruction, DETAIL_LIMIT), source: "\u8BA1\u5212\u6240\u5C5E\u6307\u4EE4" } : instructionTitle !== void 0 ? { text: truncate(instructionTitle, DETAIL_LIMIT), source: "\u6700\u65B0\u6307\u4EE4" } : { text: label, source: "\u5DE5\u4F5C\u76EE\u5F55" },
|
|
16393
16662
|
user: {
|
|
16394
16663
|
...userEntry?.title === void 0 ? {} : { title: userEntry.title },
|
|
16395
16664
|
pinned: userEntry?.pinned ?? false,
|
|
@@ -16434,14 +16703,14 @@ function createNarrativeService(options = {}) {
|
|
|
16434
16703
|
id: `${session.harness}:${session.id}`,
|
|
16435
16704
|
...session.attachedTo === void 0 ? {} : { attachedTo: session.attachedTo },
|
|
16436
16705
|
ended: session.ended,
|
|
16437
|
-
...session.sessionPlan?.availability === "available" && session.sessionPlan.steps.length > 0 ? {
|
|
16706
|
+
...session.sessionPlan?.availability === "available" && session.sessionPlan.forInstruction === "current" && session.sessionPlan.steps.length > 0 ? {
|
|
16438
16707
|
sessionPlanAllCompleted: session.sessionPlan.steps.every((step) => step.status === "completed")
|
|
16439
16708
|
} : {},
|
|
16440
16709
|
...session.attachedBy?.at === void 0 ? {} : { wrotePlanAt: session.attachedBy.at }
|
|
16441
16710
|
})), now().toISOString());
|
|
16442
16711
|
const lastWriter = [...sessionViews].filter((session) => typeof session.attachedBy?.at === "string").sort((left, right) => right.attachedBy.at.localeCompare(left.attachedBy.at))[0];
|
|
16443
|
-
const titleText = parsed?.availability === "available" && parsed.title !== void 0 ? parsed.title : pathBasename(root) || root;
|
|
16444
|
-
const titleSource = parsed?.availability === "available" && parsed.title !== void 0 ? ".wingman/plan.md H1" : "\u5DE5\u4F5C\u76EE\u5F55";
|
|
16712
|
+
const titleText = resolution?.isHome ? "\u65E0\u9879\u76EE\u76EE\u5F55(\u5BB6\u76EE\u5F55)" : parsed?.availability === "available" && parsed.title !== void 0 ? parsed.title : pathBasename(root) || root;
|
|
16713
|
+
const titleSource = resolution?.isHome ? "\u5DE5\u4F5C\u76EE\u5F55 = \u5BB6\u76EE\u5F55" : parsed?.availability === "available" && parsed.title !== void 0 ? ".wingman/plan.md H1" : "\u5DE5\u4F5C\u76EE\u5F55";
|
|
16445
16714
|
let plan;
|
|
16446
16715
|
if (parsed?.availability === "available") {
|
|
16447
16716
|
plan = {
|
|
@@ -16680,8 +16949,8 @@ function extractRawToolObservations(harness, rawLine) {
|
|
|
16680
16949
|
}
|
|
16681
16950
|
function resolveObservedPath(path, cwd) {
|
|
16682
16951
|
if (isAbsolute6(path))
|
|
16683
|
-
return
|
|
16684
|
-
return cwd === void 0 ? void 0 :
|
|
16952
|
+
return resolve11(path);
|
|
16953
|
+
return cwd === void 0 ? void 0 : resolve11(cwd, path);
|
|
16685
16954
|
}
|
|
16686
16955
|
function agentIdOf(payload) {
|
|
16687
16956
|
const id = payload.agent_id ?? payload.agentId;
|
|
@@ -16745,9 +17014,9 @@ function derive(harness, session, nowIso) {
|
|
|
16745
17014
|
const attributed = attributeSteps(steps, timeline, intervals);
|
|
16746
17015
|
const results = collectResults(lines2);
|
|
16747
17016
|
const resultBriefs = /* @__PURE__ */ new Map();
|
|
16748
|
-
for (const [toolUseId,
|
|
16749
|
-
if (
|
|
16750
|
-
resultBriefs.set(toolUseId,
|
|
17017
|
+
for (const [toolUseId, result5] of results) {
|
|
17018
|
+
if (result5.brief !== void 0)
|
|
17019
|
+
resultBriefs.set(toolUseId, result5.brief);
|
|
16751
17020
|
}
|
|
16752
17021
|
const checks = deriveCheckStats(allSteps, resultBriefs);
|
|
16753
17022
|
const todoChecks = deriveTodoCheckStats(attributed);
|
|
@@ -16856,11 +17125,16 @@ function derive(harness, session, nowIso) {
|
|
|
16856
17125
|
const activeTodos = todos.filter((todo) => todo.status === "in_progress");
|
|
16857
17126
|
const activeTodo = activeTodos.length === 1 ? activeTodos[0] : void 0;
|
|
16858
17127
|
const activeChecks = activeTodo === void 0 ? void 0 : todoChecks.get(activeTodo.id);
|
|
16859
|
-
|
|
17128
|
+
scopeSessionPlan(harness, session, lines2);
|
|
17129
|
+
const plan = workflowBase.plan.availability === "available" ? {
|
|
17130
|
+
...workflowBase.plan,
|
|
17131
|
+
forInstruction: session.sessionPlanSeq === session.instructionSeq ? "current" : "previous"
|
|
17132
|
+
} : workflowBase.plan;
|
|
16860
17133
|
const taskWorkflow = {
|
|
16861
17134
|
...workflowBase,
|
|
17135
|
+
plan,
|
|
16862
17136
|
verification: {
|
|
16863
|
-
agentMarkedComplete: plan.availability === "available" && plan.steps.length > 0 && plan.steps.every((step) => step.status === "completed"),
|
|
17137
|
+
agentMarkedComplete: plan.availability === "available" && plan.forInstruction === "current" && plan.steps.length > 0 && plan.steps.every((step) => step.status === "completed"),
|
|
16864
17138
|
checks: { ...checks, source: CHECK_STATS_SOURCE },
|
|
16865
17139
|
...activeTodo === void 0 ? {} : {
|
|
16866
17140
|
currentStep: {
|
|
@@ -16880,7 +17154,7 @@ function derive(harness, session, nowIso) {
|
|
|
16880
17154
|
...session.cwd === void 0 ? {} : { cwd: session.cwd },
|
|
16881
17155
|
...session.cwd === void 0 ? {} : {
|
|
16882
17156
|
project: {
|
|
16883
|
-
root: session.projectResolution?.root ??
|
|
17157
|
+
root: session.projectResolution?.root ?? resolve11(session.cwd),
|
|
16884
17158
|
...session.planAttachment === void 0 ? {} : { attachedTo: session.planAttachment.attachedTo }
|
|
16885
17159
|
}
|
|
16886
17160
|
},
|
|
@@ -16898,6 +17172,92 @@ function derive(harness, session, nowIso) {
|
|
|
16898
17172
|
updatedAt: nowIso
|
|
16899
17173
|
};
|
|
16900
17174
|
}
|
|
17175
|
+
function scopeSessionPlan(harness, session, lines2) {
|
|
17176
|
+
const observations = [];
|
|
17177
|
+
const seenUsers = /* @__PURE__ */ new Set();
|
|
17178
|
+
const taskIds = /* @__PURE__ */ new Set();
|
|
17179
|
+
const resultLines = /* @__PURE__ */ new Map();
|
|
17180
|
+
for (const line of lines2) {
|
|
17181
|
+
if (line.kind === "user") {
|
|
17182
|
+
for (const result5 of line.toolResults)
|
|
17183
|
+
resultLines.set(result5.toolUseId, line);
|
|
17184
|
+
}
|
|
17185
|
+
}
|
|
17186
|
+
let at;
|
|
17187
|
+
for (const line of lines2) {
|
|
17188
|
+
if (line.kind === "unknown" || line.agentId !== void 0 || line.isSidechain === true) {
|
|
17189
|
+
continue;
|
|
17190
|
+
}
|
|
17191
|
+
at = line.timestamp ?? at;
|
|
17192
|
+
const timestamp = at === void 0 ? {} : { at };
|
|
17193
|
+
if (line.kind === "user" && line.toolResults.length === 0) {
|
|
17194
|
+
const text = line.text?.trim();
|
|
17195
|
+
if (text === void 0 || text === "" || isHarnessSystemNotice(text))
|
|
17196
|
+
continue;
|
|
17197
|
+
if (line.uuid !== void 0) {
|
|
17198
|
+
if (seenUsers.has(line.uuid))
|
|
17199
|
+
continue;
|
|
17200
|
+
seenUsers.add(line.uuid);
|
|
17201
|
+
}
|
|
17202
|
+
observations.push({ kind: "instruction", source: "transcript", text, ...timestamp });
|
|
17203
|
+
} else if (line.kind === "assistant") {
|
|
17204
|
+
for (const block of line.blocks) {
|
|
17205
|
+
if (block.kind !== "tool_use")
|
|
17206
|
+
continue;
|
|
17207
|
+
if (harness === "codex" && block.name === "update_plan") {
|
|
17208
|
+
observations.push({ kind: "plan", ...timestamp });
|
|
17209
|
+
} else if (harness === "cc") {
|
|
17210
|
+
if (block.name === "TaskCreate" || block.name === "TodoWrite") {
|
|
17211
|
+
const result5 = resultLines.get(block.id);
|
|
17212
|
+
const snapshot = extractTodoSnapshots([
|
|
17213
|
+
{ ...line, blocks: [block] },
|
|
17214
|
+
...result5 === void 0 ? [] : [result5]
|
|
17215
|
+
]).at(-1);
|
|
17216
|
+
if (snapshot === void 0)
|
|
17217
|
+
continue;
|
|
17218
|
+
if (block.name === "TodoWrite")
|
|
17219
|
+
taskIds.clear();
|
|
17220
|
+
for (const todo of snapshot.todos)
|
|
17221
|
+
taskIds.add(todo.id);
|
|
17222
|
+
} else if (block.name === "TaskUpdate") {
|
|
17223
|
+
const taskId = block.input.taskId;
|
|
17224
|
+
if (typeof taskId !== "string" || !taskIds.has(taskId))
|
|
17225
|
+
continue;
|
|
17226
|
+
if (block.input.status === "deleted")
|
|
17227
|
+
taskIds.delete(taskId);
|
|
17228
|
+
} else {
|
|
17229
|
+
continue;
|
|
17230
|
+
}
|
|
17231
|
+
observations.push({ kind: "plan", ...timestamp });
|
|
17232
|
+
}
|
|
17233
|
+
}
|
|
17234
|
+
}
|
|
17235
|
+
}
|
|
17236
|
+
for (const hook of session.hookInstructions) {
|
|
17237
|
+
observations.push({ kind: "instruction", source: "hook", ...hook });
|
|
17238
|
+
}
|
|
17239
|
+
observations.sort((a, b) => (a.at ?? "").localeCompare(b.at ?? ""));
|
|
17240
|
+
session.instructionSeq = 0;
|
|
17241
|
+
session.sessionPlanSeq = 0;
|
|
17242
|
+
const instructions = /* @__PURE__ */ new Map();
|
|
17243
|
+
let unpaired;
|
|
17244
|
+
for (const observation of observations) {
|
|
17245
|
+
if (observation.kind === "plan") {
|
|
17246
|
+
session.sessionPlanSeq = session.instructionSeq;
|
|
17247
|
+
unpaired = void 0;
|
|
17248
|
+
} else if (unpaired !== void 0 && unpaired.source !== observation.source && (unpaired.text === void 0 || observation.text === void 0 || unpaired.text === observation.text)) {
|
|
17249
|
+
if (observation.text !== void 0)
|
|
17250
|
+
instructions.set(session.instructionSeq, observation.text);
|
|
17251
|
+
unpaired = void 0;
|
|
17252
|
+
} else {
|
|
17253
|
+
session.instructionSeq += 1;
|
|
17254
|
+
if (observation.text !== void 0)
|
|
17255
|
+
instructions.set(session.instructionSeq, observation.text);
|
|
17256
|
+
unpaired = observation;
|
|
17257
|
+
}
|
|
17258
|
+
}
|
|
17259
|
+
session.sessionPlanInstruction = instructions.get(session.sessionPlanSeq);
|
|
17260
|
+
}
|
|
16901
17261
|
function todoInProgressAt(timeline, ts) {
|
|
16902
17262
|
const active = timeline.filter((entry) => entry.spans.some((span) => span.status === "in_progress" && span.from !== void 0 && span.from <= ts && (span.to === void 0 || ts < span.to)));
|
|
16903
17263
|
const only = active[0];
|
|
@@ -17053,18 +17413,18 @@ function collectResults(lines2) {
|
|
|
17053
17413
|
for (const line of lines2) {
|
|
17054
17414
|
if (line.kind !== "user")
|
|
17055
17415
|
continue;
|
|
17056
|
-
for (const
|
|
17057
|
-
if (
|
|
17416
|
+
for (const result5 of line.toolResults) {
|
|
17417
|
+
if (result5.content === void 0)
|
|
17058
17418
|
continue;
|
|
17059
17419
|
const info = {};
|
|
17060
17420
|
try {
|
|
17061
|
-
info.bytes = Buffer.byteLength(JSON.stringify(
|
|
17421
|
+
info.bytes = Buffer.byteLength(JSON.stringify(result5.content), "utf8");
|
|
17062
17422
|
} catch {
|
|
17063
17423
|
}
|
|
17064
|
-
const brief = errorBrief(
|
|
17424
|
+
const brief = errorBrief(result5.content);
|
|
17065
17425
|
if (brief !== void 0)
|
|
17066
17426
|
info.brief = brief;
|
|
17067
|
-
results.set(
|
|
17427
|
+
results.set(result5.toolUseId, info);
|
|
17068
17428
|
}
|
|
17069
17429
|
}
|
|
17070
17430
|
return results;
|
|
@@ -17370,16 +17730,22 @@ function errorBrief(content) {
|
|
|
17370
17730
|
init_dist3();
|
|
17371
17731
|
init_dist5();
|
|
17372
17732
|
init_dist2();
|
|
17733
|
+
import { homedir as homedir13 } from "node:os";
|
|
17373
17734
|
import { createInterface } from "node:readline/promises";
|
|
17374
17735
|
var ProtocolUsageError = class extends Error {
|
|
17375
17736
|
};
|
|
17376
|
-
async function runProtocolCli(args) {
|
|
17737
|
+
async function runProtocolCli(args, options = { homeDir: homedir13() }) {
|
|
17377
17738
|
const parsed = parseProtocolArgs(args);
|
|
17739
|
+
if (parsed.user && parsed.harness === "dsh") {
|
|
17740
|
+
throw new ProtocolUsageError(protocolStatusDshUser(options).unsupported);
|
|
17741
|
+
}
|
|
17378
17742
|
if (parsed.action === "status") {
|
|
17379
|
-
|
|
17743
|
+
const user = getUserStatus(parsed.harness, options.homeDir);
|
|
17744
|
+
printStatus(user, "\u7528\u6237\u7EA7");
|
|
17745
|
+
printStatus(getStatus(parsed.harness, parsed.projectDir, options.homeDir), "\u9879\u76EE\u7EA7");
|
|
17380
17746
|
return 0;
|
|
17381
17747
|
}
|
|
17382
|
-
const preview = mutate(parsed
|
|
17748
|
+
const preview = mutate(parsed, options.homeDir, true);
|
|
17383
17749
|
printPreview(preview);
|
|
17384
17750
|
if (!preview.changed)
|
|
17385
17751
|
return 0;
|
|
@@ -17389,7 +17755,7 @@ async function runProtocolCli(args) {
|
|
|
17389
17755
|
process.stdout.write("wingman:\u5DF2\u53D6\u6D88\uFF0C\u672A\u5199\u5165\u4EFB\u4F55\u6587\u4EF6\u3002\n");
|
|
17390
17756
|
return 0;
|
|
17391
17757
|
}
|
|
17392
|
-
const applied = mutate(parsed
|
|
17758
|
+
const applied = mutate(parsed, options.homeDir, false);
|
|
17393
17759
|
process.stdout.write(`wingman:${parsed.harness} protocol ${parsed.action} \u5B8C\u6210
|
|
17394
17760
|
state: ${applied.state}
|
|
17395
17761
|
backupDir: ${applied.backupDir ?? "(no backup)"}
|
|
@@ -17401,12 +17767,15 @@ ${applied.message ?? ""}${applied.message === void 0 ? "" : "\n"}`);
|
|
|
17401
17767
|
function parseProtocolArgs(args) {
|
|
17402
17768
|
const [actionText, harnessText, ...tail] = args;
|
|
17403
17769
|
if (actionText !== "install" && actionText !== "uninstall" && actionText !== "status") {
|
|
17404
|
-
throw new ProtocolUsageError("protocol \u7528\u6CD5:wingman protocol install|uninstall|status <cc|codex|dsh> [--project <dir>] [--dry-run] [--yes]");
|
|
17770
|
+
throw new ProtocolUsageError("protocol \u7528\u6CD5:wingman protocol install|uninstall|status <cc|codex|dsh> [--project <dir> | --user] [--dry-run] [--yes]");
|
|
17405
17771
|
}
|
|
17406
17772
|
if (harnessText !== "cc" && harnessText !== "codex" && harnessText !== "dsh") {
|
|
17407
17773
|
throw new ProtocolUsageError(`protocol \u9700\u8981 harness \u2208 cc|codex|dsh,\u5F97\u5230 ${harnessText ?? "(\u7F3A\u53C2)"}`);
|
|
17408
17774
|
}
|
|
17409
17775
|
let projectDir = process.cwd();
|
|
17776
|
+
let user = false;
|
|
17777
|
+
let project = false;
|
|
17778
|
+
let fixtures = false;
|
|
17410
17779
|
let dryRun = false;
|
|
17411
17780
|
let yes = false;
|
|
17412
17781
|
const rest = [...tail];
|
|
@@ -17414,9 +17783,14 @@ function parseProtocolArgs(args) {
|
|
|
17414
17783
|
const arg = rest.shift();
|
|
17415
17784
|
if (arg === "--project") {
|
|
17416
17785
|
const value = rest.shift();
|
|
17417
|
-
if (value === void 0)
|
|
17786
|
+
if (value === void 0 || value.startsWith("--"))
|
|
17418
17787
|
throw new ProtocolUsageError("--project \u9700\u8981\u76EE\u5F55\u8DEF\u5F84,\u5F97\u5230(\u7F3A\u53C2)");
|
|
17788
|
+
project = true;
|
|
17419
17789
|
projectDir = value;
|
|
17790
|
+
} else if (arg === "--user") {
|
|
17791
|
+
user = true;
|
|
17792
|
+
} else if (arg === "--fixtures") {
|
|
17793
|
+
fixtures = true;
|
|
17420
17794
|
} else if (arg === "--dry-run") {
|
|
17421
17795
|
dryRun = true;
|
|
17422
17796
|
} else if (arg === "--yes") {
|
|
@@ -17425,36 +17799,57 @@ function parseProtocolArgs(args) {
|
|
|
17425
17799
|
throw new ProtocolUsageError(`protocol \u4E0D\u8BA4\u8BC6\u53C2\u6570:${arg}`);
|
|
17426
17800
|
}
|
|
17427
17801
|
}
|
|
17428
|
-
|
|
17802
|
+
if (user && project)
|
|
17803
|
+
throw new ProtocolUsageError("--user \u4E0E --project \u4E92\u65A5");
|
|
17804
|
+
if (fixtures && user)
|
|
17805
|
+
throw new ProtocolUsageError("fixtures \u6A21\u5F0F\u62D2\u7EDD --user\uFF0C\u4E0D\u80FD\u8BBF\u95EE\u7528\u6237\u7EA7\u6307\u4EE4\u6587\u4EF6");
|
|
17806
|
+
if (fixtures)
|
|
17807
|
+
throw new ProtocolUsageError("protocol \u4E0D\u652F\u6301 --fixtures");
|
|
17808
|
+
return { action: actionText, harness: harnessText, projectDir, user, dryRun, yes };
|
|
17429
17809
|
}
|
|
17430
|
-
function getStatus(harness, projectDir) {
|
|
17810
|
+
function getStatus(harness, projectDir, homeDir) {
|
|
17431
17811
|
switch (harness) {
|
|
17432
17812
|
case "cc":
|
|
17433
|
-
return protocolStatusCc({ projectDir });
|
|
17813
|
+
return protocolStatusCc({ projectDir, homeDir });
|
|
17434
17814
|
case "codex":
|
|
17435
|
-
return protocolStatusCodex({ projectDir });
|
|
17815
|
+
return protocolStatusCodex({ projectDir, homeDir });
|
|
17436
17816
|
case "dsh":
|
|
17437
|
-
return protocolStatusDsh({ projectDir });
|
|
17817
|
+
return protocolStatusDsh({ projectDir, homeDir });
|
|
17438
17818
|
}
|
|
17439
17819
|
}
|
|
17440
|
-
function
|
|
17820
|
+
function getUserStatus(harness, homeDir) {
|
|
17441
17821
|
switch (harness) {
|
|
17442
17822
|
case "cc":
|
|
17443
|
-
return
|
|
17823
|
+
return protocolStatusCcUser({ homeDir });
|
|
17444
17824
|
case "codex":
|
|
17445
|
-
return
|
|
17825
|
+
return protocolStatusCodexUser({ homeDir });
|
|
17446
17826
|
case "dsh":
|
|
17447
|
-
return
|
|
17827
|
+
return protocolStatusDshUser({ homeDir });
|
|
17448
17828
|
}
|
|
17449
17829
|
}
|
|
17450
|
-
function
|
|
17451
|
-
|
|
17452
|
-
|
|
17453
|
-
|
|
17454
|
-
|
|
17455
|
-
|
|
17456
|
-
|
|
17457
|
-
|
|
17830
|
+
function mutate(parsed, homeDir, dryRun) {
|
|
17831
|
+
const { action, harness, projectDir, user } = parsed;
|
|
17832
|
+
switch (harness) {
|
|
17833
|
+
case "cc":
|
|
17834
|
+
return action === "install" ? (user ? installProtocolCcUser : installProtocolCc)({ projectDir, homeDir, dryRun }) : (user ? uninstallProtocolCcUser : uninstallProtocolCc)({ projectDir, homeDir, dryRun });
|
|
17835
|
+
case "codex":
|
|
17836
|
+
return action === "install" ? (user ? installProtocolCodexUser : installProtocolCodex)({ projectDir, homeDir, dryRun }) : (user ? uninstallProtocolCodexUser : uninstallProtocolCodex)({
|
|
17837
|
+
projectDir,
|
|
17838
|
+
homeDir,
|
|
17839
|
+
dryRun
|
|
17840
|
+
});
|
|
17841
|
+
case "dsh":
|
|
17842
|
+
return action === "install" ? installProtocolDsh({ projectDir, homeDir, dryRun }) : uninstallProtocolDsh({ projectDir, homeDir, dryRun });
|
|
17843
|
+
}
|
|
17844
|
+
}
|
|
17845
|
+
function printStatus(value, scope) {
|
|
17846
|
+
if ("unsupported" in value) {
|
|
17847
|
+
process.stdout.write(`${scope}: unsupported \u2014 ${value.unsupported}
|
|
17848
|
+
`);
|
|
17849
|
+
return;
|
|
17850
|
+
}
|
|
17851
|
+
process.stdout.write(`${scope}: ${value.state} | target: ${value.targetPath} | state: ${value.state}${value.version === void 0 ? "" : ` | version: ${value.version}`}${value.message === void 0 ? "" : ` | ${value.message}`}${value.reason === void 0 ? "" : ` | reason: ${value.reason}`}
|
|
17852
|
+
`);
|
|
17458
17853
|
}
|
|
17459
17854
|
function printPreview(value) {
|
|
17460
17855
|
process.stdout.write(`${unifiedDiff(value.targetPath, value.before, value.after)}
|
|
@@ -17504,8 +17899,8 @@ async function confirmWrite() {
|
|
|
17504
17899
|
}
|
|
17505
17900
|
|
|
17506
17901
|
// apps/cli/dist/registry.js
|
|
17507
|
-
import { existsSync as
|
|
17508
|
-
import { homedir as
|
|
17902
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
17903
|
+
import { homedir as homedir14 } from "node:os";
|
|
17509
17904
|
async function importHarnessModule(harness) {
|
|
17510
17905
|
const mod = await importAdapterModule(harness);
|
|
17511
17906
|
if (typeof mod.createAdapter !== "function") {
|
|
@@ -17527,7 +17922,7 @@ function importAdapterModule(harness) {
|
|
|
17527
17922
|
}
|
|
17528
17923
|
}
|
|
17529
17924
|
function fixtureScanOptions(harness) {
|
|
17530
|
-
if (!
|
|
17925
|
+
if (!existsSync14(fixturePath())) {
|
|
17531
17926
|
throw new Error("--fixtures \u9700\u8981\u4ED3\u5E93\u5185\u7684 packages/fixtures \u6570\u636E;\u53D1\u5E03\u5B89\u88C5\u5305/npx \u4EA7\u7269\u4E0D\u5305\u542B\u6837\u4F8B");
|
|
17532
17927
|
}
|
|
17533
17928
|
switch (harness) {
|
|
@@ -17548,16 +17943,16 @@ async function loadHarness(harness, mode) {
|
|
|
17548
17943
|
return {
|
|
17549
17944
|
harness,
|
|
17550
17945
|
adapter,
|
|
17551
|
-
scanOptions: mode.fixtures ? fixtureScanOptions(harness) : { homeDir:
|
|
17946
|
+
scanOptions: mode.fixtures ? fixtureScanOptions(harness) : { homeDir: homedir14() },
|
|
17552
17947
|
feedbackSignals
|
|
17553
17948
|
};
|
|
17554
17949
|
}
|
|
17555
17950
|
|
|
17556
17951
|
// apps/cli/dist/runtime-state.js
|
|
17557
17952
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
17558
|
-
import { closeSync as closeSync3, mkdirSync as
|
|
17559
|
-
import { homedir as
|
|
17560
|
-
import { dirname as
|
|
17953
|
+
import { closeSync as closeSync3, mkdirSync as mkdirSync12, openSync as openSync3, readFileSync as readFileSync17, renameSync as renameSync5, rmSync as rmSync10, writeFileSync as writeFileSync13 } from "node:fs";
|
|
17954
|
+
import { homedir as homedir15 } from "node:os";
|
|
17955
|
+
import { dirname as dirname18, join as join26 } from "node:path";
|
|
17561
17956
|
function createHookToken() {
|
|
17562
17957
|
return randomBytes4(32).toString("base64url");
|
|
17563
17958
|
}
|
|
@@ -17568,15 +17963,15 @@ function writeServeRuntimeState(port, token, options = {}) {
|
|
|
17568
17963
|
const pid = options.pid ?? process.pid;
|
|
17569
17964
|
const suffix = randomBytes4(8).toString("base64url");
|
|
17570
17965
|
const owner = `serve-${startedAtMs}-${pid}-${suffix}`;
|
|
17571
|
-
const path =
|
|
17572
|
-
const tempPath =
|
|
17966
|
+
const path = join26(options.homeDir ?? homedir15(), ".wingman", "state", "serve", `${owner}.json`);
|
|
17967
|
+
const tempPath = join26(dirname18(path), `.${owner}.tmp`);
|
|
17573
17968
|
const contents = Buffer.from(`${JSON.stringify({ version: 2, owner, pid, port, startedAtMs, token })}
|
|
17574
17969
|
`, "utf8");
|
|
17575
17970
|
let fd;
|
|
17576
17971
|
try {
|
|
17577
|
-
|
|
17972
|
+
mkdirSync12(dirname18(path), { recursive: true, mode: 448 });
|
|
17578
17973
|
fd = openSync3(tempPath, "wx", 384);
|
|
17579
|
-
|
|
17974
|
+
writeFileSync13(fd, contents);
|
|
17580
17975
|
closeSync3(fd);
|
|
17581
17976
|
fd = void 0;
|
|
17582
17977
|
renameSync5(tempPath, path);
|
|
@@ -17589,7 +17984,7 @@ function writeServeRuntimeState(port, token, options = {}) {
|
|
|
17589
17984
|
}
|
|
17590
17985
|
}
|
|
17591
17986
|
try {
|
|
17592
|
-
|
|
17987
|
+
rmSync10(tempPath, { force: true });
|
|
17593
17988
|
} catch {
|
|
17594
17989
|
}
|
|
17595
17990
|
warn(`Codex hook \u8FD0\u884C\u6001\u5199\u5165\u5931\u8D25,\u9762\u677F\u7EE7\u7EED\u8FD0\u884C:${errorMessage2(error)}`);
|
|
@@ -17600,9 +17995,9 @@ function removeServeRuntimeState(registration) {
|
|
|
17600
17995
|
if (registration === void 0)
|
|
17601
17996
|
return;
|
|
17602
17997
|
try {
|
|
17603
|
-
const current =
|
|
17998
|
+
const current = readFileSync17(registration.path);
|
|
17604
17999
|
if (current.equals(registration.contents))
|
|
17605
|
-
|
|
18000
|
+
rmSync10(registration.path, { force: true });
|
|
17606
18001
|
} catch {
|
|
17607
18002
|
}
|
|
17608
18003
|
}
|
|
@@ -17623,17 +18018,19 @@ async function scanValidated(adapter, options) {
|
|
|
17623
18018
|
}
|
|
17624
18019
|
|
|
17625
18020
|
// apps/cli/dist/server.js
|
|
18021
|
+
init_dist3();
|
|
18022
|
+
init_dist5();
|
|
17626
18023
|
init_dist();
|
|
17627
18024
|
import { execFile as execFile2 } from "node:child_process";
|
|
17628
18025
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
17629
18026
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
17630
18027
|
import { createServer } from "node:http";
|
|
17631
|
-
import { extname, resolve as
|
|
18028
|
+
import { extname, resolve as resolve13, sep as sep2 } from "node:path";
|
|
17632
18029
|
|
|
17633
18030
|
// apps/cli/dist/return-target.js
|
|
17634
18031
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
17635
|
-
import { closeSync as closeSync4, copyFileSync as copyFileSync2, mkdirSync as
|
|
17636
|
-
import { dirname as
|
|
18032
|
+
import { closeSync as closeSync4, copyFileSync as copyFileSync2, mkdirSync as mkdirSync13, openSync as openSync4, readFileSync as readFileSync18, renameSync as renameSync6, rmSync as rmSync11, statSync as statSync6, writeFileSync as writeFileSync14 } from "node:fs";
|
|
18033
|
+
import { dirname as dirname19, join as join27, resolve as resolve12 } from "node:path";
|
|
17637
18034
|
var BUNDLES = [
|
|
17638
18035
|
["Terminal", "Terminal.app"],
|
|
17639
18036
|
["iTerm", "iTerm.app"],
|
|
@@ -17644,11 +18041,11 @@ var BUNDLES = [
|
|
|
17644
18041
|
["kitty", "kitty.app"],
|
|
17645
18042
|
["VS Code", "Visual Studio Code.app"]
|
|
17646
18043
|
];
|
|
17647
|
-
function detectReturnTargets(homeDir, roots = ["/Applications",
|
|
18044
|
+
function detectReturnTargets(homeDir, roots = ["/Applications", join27(homeDir, "Applications")]) {
|
|
17648
18045
|
const available = [];
|
|
17649
18046
|
for (const [name, bundle] of BUNDLES) {
|
|
17650
|
-
for (const root of new Set(roots.map((root2) =>
|
|
17651
|
-
const bundlePath =
|
|
18047
|
+
for (const root of new Set(roots.map((root2) => resolve12(root2)))) {
|
|
18048
|
+
const bundlePath = join27(root, bundle);
|
|
17652
18049
|
try {
|
|
17653
18050
|
if (statSync6(bundlePath).isDirectory())
|
|
17654
18051
|
available.push({ name, bundlePath });
|
|
@@ -17659,12 +18056,12 @@ function detectReturnTargets(homeDir, roots = ["/Applications", join24(homeDir,
|
|
|
17659
18056
|
return available;
|
|
17660
18057
|
}
|
|
17661
18058
|
function settingsPath(homeDir) {
|
|
17662
|
-
return
|
|
18059
|
+
return join27(homeDir, ".wingman", "state", "settings.json");
|
|
17663
18060
|
}
|
|
17664
18061
|
function readReturnTargetSettings(homeDir) {
|
|
17665
18062
|
let raw;
|
|
17666
18063
|
try {
|
|
17667
|
-
raw =
|
|
18064
|
+
raw = readFileSync18(settingsPath(homeDir), "utf8");
|
|
17668
18065
|
} catch (error) {
|
|
17669
18066
|
if (isRecord8(error) && error.code === "ENOENT")
|
|
17670
18067
|
return { version: 1 };
|
|
@@ -17685,10 +18082,10 @@ function saveReturnTarget(homeDir, bundlePath) {
|
|
|
17685
18082
|
return current;
|
|
17686
18083
|
const settings = { version: 1, returnTarget: { bundlePath } };
|
|
17687
18084
|
const path = settingsPath(homeDir);
|
|
17688
|
-
const tempPath =
|
|
18085
|
+
const tempPath = join27(dirname19(path), `.settings-${randomBytes5(8).toString("hex")}.tmp`);
|
|
17689
18086
|
let fd;
|
|
17690
18087
|
try {
|
|
17691
|
-
|
|
18088
|
+
mkdirSync13(dirname19(path), { recursive: true, mode: 448 });
|
|
17692
18089
|
try {
|
|
17693
18090
|
copyFileSync2(path, `${path}.bak`);
|
|
17694
18091
|
} catch (error) {
|
|
@@ -17696,7 +18093,7 @@ function saveReturnTarget(homeDir, bundlePath) {
|
|
|
17696
18093
|
throw error;
|
|
17697
18094
|
}
|
|
17698
18095
|
fd = openSync4(tempPath, "wx", 384);
|
|
17699
|
-
|
|
18096
|
+
writeFileSync14(fd, `${JSON.stringify(settings)}
|
|
17700
18097
|
`, "utf8");
|
|
17701
18098
|
closeSync4(fd);
|
|
17702
18099
|
fd = void 0;
|
|
@@ -17712,7 +18109,7 @@ function saveReturnTarget(homeDir, bundlePath) {
|
|
|
17712
18109
|
}
|
|
17713
18110
|
}
|
|
17714
18111
|
try {
|
|
17715
|
-
|
|
18112
|
+
rmSync11(tempPath, { force: true });
|
|
17716
18113
|
} catch {
|
|
17717
18114
|
}
|
|
17718
18115
|
}
|
|
@@ -18037,8 +18434,15 @@ async function handle(req, res, options, warn, runtime) {
|
|
|
18037
18434
|
}
|
|
18038
18435
|
if (url.pathname === "/api/anatomy") {
|
|
18039
18436
|
const configs = await scanAll(options.harnesses, warn);
|
|
18437
|
+
const anatomy = configs.map((config) => {
|
|
18438
|
+
const homeDir = options.harnesses.find((entry) => entry.harness === config.harness)?.scanOptions.homeDir ?? options.homeDir;
|
|
18439
|
+
if (homeDir === void 0)
|
|
18440
|
+
throw new Error("anatomy \u9700\u8981\u663E\u5F0F homeDir");
|
|
18441
|
+
const user = config.harness === "cc" ? protocolStatusCcUser({ homeDir }).state : config.harness === "codex" ? protocolStatusCodexUser({ homeDir }).state : "unsupported";
|
|
18442
|
+
return { ...config, planProtocol: { user } };
|
|
18443
|
+
});
|
|
18040
18444
|
res.writeHead(200, { "content-type": "application/json; charset=utf-8" });
|
|
18041
|
-
res.end(JSON.stringify(
|
|
18445
|
+
res.end(JSON.stringify(anatomy));
|
|
18042
18446
|
return;
|
|
18043
18447
|
}
|
|
18044
18448
|
if (url.pathname === "/api/version") {
|
|
@@ -18199,11 +18603,11 @@ async function handleActionApply(req, res, options, runtime) {
|
|
|
18199
18603
|
return;
|
|
18200
18604
|
}
|
|
18201
18605
|
try {
|
|
18202
|
-
const
|
|
18203
|
-
if (
|
|
18606
|
+
const result5 = await loaded.adapter.applyAction(plan, loaded.scanOptions);
|
|
18607
|
+
if (result5.ok) {
|
|
18204
18608
|
runtime.anatomy = null;
|
|
18205
18609
|
}
|
|
18206
|
-
sendJson2(res, 200,
|
|
18610
|
+
sendJson2(res, 200, result5);
|
|
18207
18611
|
} catch (error) {
|
|
18208
18612
|
sendJson2(res, 400, { error: errorMessage3(error) });
|
|
18209
18613
|
}
|
|
@@ -18283,12 +18687,12 @@ async function handleTaskOverlay(req, res, options) {
|
|
|
18283
18687
|
return;
|
|
18284
18688
|
}
|
|
18285
18689
|
const key = `${body.harness}:${body.sessionId}`;
|
|
18286
|
-
const
|
|
18287
|
-
if ("unavailable" in
|
|
18288
|
-
sendJson2(res, 409, { error:
|
|
18690
|
+
const result5 = patchTaskOverlay(options.homeDir, key, body.patch, /* @__PURE__ */ new Date());
|
|
18691
|
+
if ("unavailable" in result5) {
|
|
18692
|
+
sendJson2(res, 409, { error: result5.unavailable });
|
|
18289
18693
|
return;
|
|
18290
18694
|
}
|
|
18291
|
-
sendJson2(res, 200, { key, entry:
|
|
18695
|
+
sendJson2(res, 200, { key, entry: result5.entry });
|
|
18292
18696
|
}
|
|
18293
18697
|
var LICENSE_BODY_LIMIT = 64 * 1024;
|
|
18294
18698
|
async function handleLicenseInstall(req, res, options) {
|
|
@@ -18297,12 +18701,12 @@ async function handleLicenseInstall(req, res, options) {
|
|
|
18297
18701
|
sendJson2(res, 400, { error: "license \u6587\u4EF6\u8D85\u8FC7 64KB \u4E0A\u9650\u6216\u8BFB\u53D6\u5931\u8D25" });
|
|
18298
18702
|
return;
|
|
18299
18703
|
}
|
|
18300
|
-
const
|
|
18301
|
-
if (!
|
|
18302
|
-
sendJson2(res, 400, { error:
|
|
18704
|
+
const result5 = installLicense(raw, options.licenseOptions);
|
|
18705
|
+
if (!result5.ok) {
|
|
18706
|
+
sendJson2(res, 400, { error: result5.error });
|
|
18303
18707
|
return;
|
|
18304
18708
|
}
|
|
18305
|
-
sendJson2(res, 200, publicLicenseStatus(
|
|
18709
|
+
sendJson2(res, 200, publicLicenseStatus(result5.status));
|
|
18306
18710
|
}
|
|
18307
18711
|
async function handleLicenseRefresh(res, options) {
|
|
18308
18712
|
const homeDir = options.licenseRefreshOptions?.homeDir ?? options.licenseOptions?.homeDir;
|
|
@@ -18314,11 +18718,11 @@ async function handleLicenseRefresh(res, options) {
|
|
|
18314
18718
|
...publicKeyPem === void 0 ? {} : { publicKeyPem },
|
|
18315
18719
|
...now === void 0 ? {} : { now }
|
|
18316
18720
|
};
|
|
18317
|
-
const
|
|
18318
|
-
if (!
|
|
18721
|
+
const result5 = await refreshLicense(refreshOptions);
|
|
18722
|
+
if (!result5.ok) {
|
|
18319
18723
|
sendJson2(res, 400, {
|
|
18320
|
-
error:
|
|
18321
|
-
canSubscribe:
|
|
18724
|
+
error: result5.message,
|
|
18725
|
+
canSubscribe: result5.reason === "inactive"
|
|
18322
18726
|
});
|
|
18323
18727
|
return;
|
|
18324
18728
|
}
|
|
@@ -18330,7 +18734,7 @@ async function handleLicenseRefresh(res, options) {
|
|
|
18330
18734
|
};
|
|
18331
18735
|
sendJson2(res, 200, {
|
|
18332
18736
|
...publicLicenseStatus(licenseStatus(statusOptions)),
|
|
18333
|
-
message:
|
|
18737
|
+
message: result5.message
|
|
18334
18738
|
});
|
|
18335
18739
|
}
|
|
18336
18740
|
function publicLicenseStatus(status3) {
|
|
@@ -18425,8 +18829,8 @@ async function serveStatic(pathname, res, panelDistDir) {
|
|
|
18425
18829
|
return;
|
|
18426
18830
|
}
|
|
18427
18831
|
const rel = decoded === "/" ? "/index.html" : decoded;
|
|
18428
|
-
const distDir =
|
|
18429
|
-
const filePath =
|
|
18832
|
+
const distDir = resolve13(panelDistDir);
|
|
18833
|
+
const filePath = resolve13(distDir, `.${rel}`);
|
|
18430
18834
|
if (filePath !== distDir && !filePath.startsWith(distDir + sep2)) {
|
|
18431
18835
|
sendText2(res, 403, "forbidden");
|
|
18432
18836
|
return;
|
|
@@ -18463,8 +18867,8 @@ var HELP = `wingman \u2014 Not your copilot. Your wingman.
|
|
|
18463
18867
|
wingman hook install <harness> [--port 7333] \u5B9E\u51B5\u63A5\u7EBF(\u5199\u524D\u5907\u4EFD,\u5E42\u7B49)
|
|
18464
18868
|
[--profile <p>] dsh:\u53EA\u5904\u7406\u6307\u5B9A profile
|
|
18465
18869
|
wingman hook uninstall <harness> [--profile <p>] \u89E3\u7EBF(\u914D\u7F6E\u6062\u590D,\u5E42\u7B49)
|
|
18466
|
-
wingman protocol install|uninstall|status <harness> \
|
|
18467
|
-
[--project <dir>] [--dry-run] [--yes]
|
|
18870
|
+
wingman protocol install|uninstall|status <harness> \u7BA1\u7406\u7528\u6237\u7EA7 / \u9879\u76EE\u7EA7 Plan Protocol
|
|
18871
|
+
[--project <dir> | --user] [--dry-run] [--yes]
|
|
18468
18872
|
wingman license status \u67E5\u770B\u8BA2\u9605\u72B6\u6001(\u5199\u52A8\u4F5C\u7684\u95F8)
|
|
18469
18873
|
wingman license refresh \u8054\u7F51\u5411\u7B7E\u53D1\u7AEF\u6362\u65B0 license(\u7EED\u671F)
|
|
18470
18874
|
wingman --version | -v | version \u663E\u793A\u7248\u672C
|
|
@@ -18493,7 +18897,7 @@ async function main(argv) {
|
|
|
18493
18897
|
case "hook":
|
|
18494
18898
|
return runHook(rest);
|
|
18495
18899
|
case "protocol":
|
|
18496
|
-
return runProtocolCli(rest);
|
|
18900
|
+
return runProtocolCli(rest, { homeDir: homedir16() });
|
|
18497
18901
|
case "license": {
|
|
18498
18902
|
if (rest[0] === "status") {
|
|
18499
18903
|
const status3 = licenseStatus();
|
|
@@ -18502,10 +18906,10 @@ async function main(argv) {
|
|
|
18502
18906
|
return 0;
|
|
18503
18907
|
}
|
|
18504
18908
|
if (rest[0] === "refresh") {
|
|
18505
|
-
const
|
|
18506
|
-
process.stdout.write(`${
|
|
18909
|
+
const result5 = await refreshLicense();
|
|
18910
|
+
process.stdout.write(`${result5.message}
|
|
18507
18911
|
`);
|
|
18508
|
-
if (!
|
|
18912
|
+
if (!result5.ok)
|
|
18509
18913
|
return 1;
|
|
18510
18914
|
const status3 = licenseStatus();
|
|
18511
18915
|
process.stdout.write(`${status3.state}:${status3.detail}
|
|
@@ -18544,7 +18948,7 @@ ${counts}
|
|
|
18544
18948
|
}
|
|
18545
18949
|
async function runServe(args) {
|
|
18546
18950
|
const { port, fixtures, panelDist } = parseServeArgs(args);
|
|
18547
|
-
const homeDir = fixtures ? fixturesRoot :
|
|
18951
|
+
const homeDir = fixtures ? fixturesRoot : homedir16();
|
|
18548
18952
|
const hookToken = createHookToken();
|
|
18549
18953
|
let dshRetirementNotice;
|
|
18550
18954
|
if (!fixtures) {
|
|
@@ -18579,7 +18983,7 @@ async function runServe(args) {
|
|
|
18579
18983
|
`);
|
|
18580
18984
|
}
|
|
18581
18985
|
}
|
|
18582
|
-
const panelDistDir = panelDist === void 0 ?
|
|
18986
|
+
const panelDistDir = panelDist === void 0 ? resolve14(dirname20(fileURLToPath2(import.meta.url)), "../../panel/dist") : resolve14(panelDist);
|
|
18583
18987
|
const narrative = createNarrativeService({
|
|
18584
18988
|
followTranscripts: !fixtures,
|
|
18585
18989
|
homeDir,
|
|
@@ -18592,7 +18996,7 @@ async function runServe(args) {
|
|
|
18592
18996
|
});
|
|
18593
18997
|
if (fixtures) {
|
|
18594
18998
|
try {
|
|
18595
|
-
const raw =
|
|
18999
|
+
const raw = readFileSync19(fixturePath("cc", "sessions", "session-todos.jsonl"), "utf8");
|
|
18596
19000
|
narrative.seedFixture("cc", raw.split("\n"), "MOCK \u2014 fixtures \u6F14\u793A:\u53D9\u4E8B\u6570\u636E\u6765\u81EA packages/fixtures \u7684 session-todos.jsonl \u6837\u4F8B\u4F1A\u8BDD,\u975E\u672C\u673A\u771F\u5B9E transcript\u3002");
|
|
18597
19001
|
} catch (error) {
|
|
18598
19002
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -18666,8 +19070,8 @@ async function runHook(args) {
|
|
|
18666
19070
|
const { adapter, scanOptions } = await loadHarness(harness, { fixtures: false });
|
|
18667
19071
|
if (action === "install") {
|
|
18668
19072
|
if (harness === "dsh") {
|
|
18669
|
-
const
|
|
18670
|
-
writeDshInstallReport(await dshHookInstallReport(scanOptions),
|
|
19073
|
+
const result5 = await installDshHooks(port, scanOptions);
|
|
19074
|
+
writeDshInstallReport(await dshHookInstallReport(scanOptions), result5);
|
|
18671
19075
|
process.stdout.write(`wingman:dsh profile \u63A5\u7EBF\u5904\u7406\u5B8C\u6210(POST http://127.0.0.1:${port}/hook?harness=dsh)\u3002
|
|
18672
19076
|
\u5199\u524D\u5DF2\u5907\u4EFD;\u91CD\u590D\u6267\u884C\u5E42\u7B49;\u89E3\u7EBF:wingman hook uninstall dsh
|
|
18673
19077
|
`);
|
|
@@ -18681,14 +19085,14 @@ async function runHook(args) {
|
|
|
18681
19085
|
`);
|
|
18682
19086
|
}
|
|
18683
19087
|
} else if (harness === "dsh") {
|
|
18684
|
-
const
|
|
19088
|
+
const result5 = await uninstallDshHooks(scanOptions);
|
|
18685
19089
|
const messages = {
|
|
18686
19090
|
unwired: "\u5DF2\u89E3\u7EBF",
|
|
18687
19091
|
state: "\u5DF2\u6062\u590D",
|
|
18688
19092
|
removed: "\u5DF2\u79FB\u9664\u6B8B\u7559\u5757",
|
|
18689
19093
|
cleared: "\u5DF2\u6E05\u7406\u8BB0\u5F55"
|
|
18690
19094
|
};
|
|
18691
|
-
for (const profile2 of
|
|
19095
|
+
for (const profile2 of result5.profiles) {
|
|
18692
19096
|
process.stdout.write(`${profile2.profile}:${messages[profile2.restored]}
|
|
18693
19097
|
`);
|
|
18694
19098
|
}
|
|
@@ -18709,16 +19113,16 @@ function writeDshInstallReport(report, installResult) {
|
|
|
18709
19113
|
process.stdout.write("\u672A\u53D1\u73B0\u542B package.json \u7684 dsh profile\u3002\n");
|
|
18710
19114
|
return;
|
|
18711
19115
|
}
|
|
18712
|
-
for (const
|
|
18713
|
-
if (
|
|
18714
|
-
process.stdout.write(`${
|
|
19116
|
+
for (const result5 of report.profiles) {
|
|
19117
|
+
if (result5.wired) {
|
|
19118
|
+
process.stdout.write(`${result5.profile}:\u5DF2\u63A5\u7EBF
|
|
18715
19119
|
`);
|
|
18716
|
-
} else if (
|
|
18717
|
-
const removed = installResult.removedProfiles.includes(
|
|
18718
|
-
process.stdout.write(`${
|
|
19120
|
+
} else if (result5.missingPackages.length > 0) {
|
|
19121
|
+
const removed = installResult.removedProfiles.includes(result5.profile) ? "\u5DF2\u79FB\u9664\u65E7\u63A5\u7EBF\u5757," : "";
|
|
19122
|
+
process.stdout.write(`${result5.profile}:\u672A\u63A5\u7EBF,${removed}\u7F3A ${result5.missingPackages.join("\u3001")} \u2192 ${result5.installCommand ?? ""}
|
|
18719
19123
|
`);
|
|
18720
19124
|
} else {
|
|
18721
|
-
process.stdout.write(`${
|
|
19125
|
+
process.stdout.write(`${result5.profile}:\u672A\u63A5\u7EBF
|
|
18722
19126
|
`);
|
|
18723
19127
|
}
|
|
18724
19128
|
}
|
|
@@ -18798,7 +19202,7 @@ main(process.argv.slice(2)).then((code) => {
|
|
|
18798
19202
|
process.stderr.write(`
|
|
18799
19203
|
${HELP}`);
|
|
18800
19204
|
}
|
|
18801
|
-
process.exitCode = 1;
|
|
19205
|
+
process.exitCode = error instanceof ProtocolUsageError ? 2 : 1;
|
|
18802
19206
|
});
|
|
18803
19207
|
/*! Bundled license information:
|
|
18804
19208
|
|