driftseal 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/README.zh-CN.md +2 -1
- package/bin/driftseal.js +43 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,8 +73,9 @@ driftseal skill install --target kimi-code --scope global
|
|
|
73
73
|
| `cursor` | `.cursor/skills/use-driftseal` | `~/.cursor/skills/use-driftseal` |
|
|
74
74
|
|
|
75
75
|
Use `--root <repository>` to select a project when running the installer
|
|
76
|
-
elsewhere. Repeated installs of identical content are no-ops
|
|
77
|
-
|
|
76
|
+
elsewhere. Repeated installs of identical content are no-ops, and a skill left
|
|
77
|
+
by an earlier DriftSeal release is upgraded in place; only a skill this
|
|
78
|
+
installer never wrote requires `--force`. MCP and lifecycle hooks are optional
|
|
78
79
|
adapters; enable them only for a concrete host constraint or reminder need, not
|
|
79
80
|
as additional policy layers.
|
|
80
81
|
|
package/README.zh-CN.md
CHANGED
|
@@ -71,7 +71,8 @@ driftseal skill install --target kimi-code --scope global
|
|
|
71
71
|
| `cursor` | `.cursor/skills/use-driftseal` | `~/.cursor/skills/use-driftseal` |
|
|
72
72
|
|
|
73
73
|
如果不在目标 repository 中执行,用 `--root <repository>` 明确指定项目。
|
|
74
|
-
|
|
74
|
+
重复安装相同内容不会产生改动;旧版本 DriftSeal 装下的 skill 会被直接原地升级,
|
|
75
|
+
只有安装器从未写过的 skill 才需要显式传入 `--force`。
|
|
75
76
|
MCP 与 lifecycle hook 都是可选适配层;只有确实存在 host 限制或提醒需求时
|
|
76
77
|
才启用,不要把它们叠成额外的 policy 层。
|
|
77
78
|
|
package/bin/driftseal.js
CHANGED
|
@@ -1984,6 +1984,27 @@ function installMcp(request) {
|
|
|
1984
1984
|
|
|
1985
1985
|
const SKILL_NAME = 'use-driftseal';
|
|
1986
1986
|
|
|
1987
|
+
/*
|
|
1988
|
+
* Every skill tree DriftSeal has ever bundled, oldest first, as skillTreeDigest
|
|
1989
|
+
* hashes. `skill install` treats a directory matching one of these as its own
|
|
1990
|
+
* earlier output and upgrades it in place; anything else is someone's local
|
|
1991
|
+
* skill that only --force may replace. Append the new digest whenever the
|
|
1992
|
+
* bundled skill changes, otherwise the next release cannot upgrade this one;
|
|
1993
|
+
* the "bundled use-driftseal skill is a known release" test fails until you do.
|
|
1994
|
+
*/
|
|
1995
|
+
const SKILL_RELEASE_DIGESTS = new Set([
|
|
1996
|
+
'e996627c96edc7c09599bc454c4225a416aa89e50aef14d4dd569dd21454e882', // 1b76215 initial commit
|
|
1997
|
+
'5f702545b18e117bafcea669b48cdb3b31c98079f97eaa084fd3b4ceff9500e8', // 5c2ec74 intents only for rollback-worthy changes
|
|
1998
|
+
'77f6365590ff181ee6be003930dd1696c363e213368de0f4e89962555af3fabe', // 56380a8 local MCP server
|
|
1999
|
+
'b7e2310eaf20b50b5ec28531471965607e7e070a4f58263e29408b2cd5cdfb11', // 1cc77f6 reclaim markers
|
|
2000
|
+
'08bc63b8dcf0f4f078252179a3fc2ca4ef2632ecb5b9dfe3782a452c3202c2c4', // de4a8a1 skill slimmed into a usage guide
|
|
2001
|
+
'8523459ff81cf0b97a36b30d216956a58d8a3b3b9760f455d7ea334604da335a', // 3a1d6e0 protocol v7 resume semantics
|
|
2002
|
+
'cc98b9348ec222320bfcd285ba3f1f499a42d15b31e9b1d83c35f0206b2d5ba9', // ca16785 CLI-first skill integration
|
|
2003
|
+
'0fd870f8c1b81f8386d986d64742679d56cd1d317c02890830c81876eb9227d6', // da8afd2 1.1.0 absorb
|
|
2004
|
+
'72ddea79940bdf2bce66d491888f11423ae1bd383e1b511028fda617e6f6fb27', // f395778 1.1.6 parked intents
|
|
2005
|
+
'df8bc7035de1a19faf307c92f9bb0f4052e683d1a94881c2c5d5cbef48b67568', // dc9899d 1.1.7 parked intents in absorb (current)
|
|
2006
|
+
]);
|
|
2007
|
+
|
|
1987
2008
|
function skillInstallUsage() {
|
|
1988
2009
|
return 'usage: driftseal skill install --target <codex|kimi-code|opencode|claude-code|cursor> [--scope project|global] [--root <repository>] [--force]';
|
|
1989
2010
|
}
|
|
@@ -2046,7 +2067,13 @@ function parseSkillInstallRequest(argv) {
|
|
|
2046
2067
|
};
|
|
2047
2068
|
}
|
|
2048
2069
|
|
|
2049
|
-
|
|
2070
|
+
/*
|
|
2071
|
+
* Identifies a skill tree by its contents alone: relative paths joined with "/"
|
|
2072
|
+
* and file bytes, never file modes or timestamps. The digest therefore stays
|
|
2073
|
+
* stable across platforms, checkouts, and npm tarballs, which is what lets
|
|
2074
|
+
* SKILL_RELEASE_DIGESTS recognize a skill DriftSeal installed earlier.
|
|
2075
|
+
*/
|
|
2076
|
+
function skillTreeDigest(directory) {
|
|
2050
2077
|
if (!fs.existsSync(directory)) return null;
|
|
2051
2078
|
const digest = crypto.createHash('sha256');
|
|
2052
2079
|
|
|
@@ -2055,12 +2082,12 @@ function directoryDigest(directory) {
|
|
|
2055
2082
|
if (stat.isDirectory()) {
|
|
2056
2083
|
digest.update(`directory\0${relative}\0`);
|
|
2057
2084
|
for (const name of fs.readdirSync(current).sort()) {
|
|
2058
|
-
visit(path.join(current, name), relative ?
|
|
2085
|
+
visit(path.join(current, name), relative ? `${relative}/${name}` : name);
|
|
2059
2086
|
}
|
|
2060
2087
|
return;
|
|
2061
2088
|
}
|
|
2062
2089
|
if (stat.isFile()) {
|
|
2063
|
-
digest.update(`file\0${relative}\0
|
|
2090
|
+
digest.update(`file\0${relative}\0`);
|
|
2064
2091
|
digest.update(fs.readFileSync(current));
|
|
2065
2092
|
digest.update('\0');
|
|
2066
2093
|
return;
|
|
@@ -2069,7 +2096,7 @@ function directoryDigest(directory) {
|
|
|
2069
2096
|
digest.update(`symlink\0${relative}\0${fs.readlinkSync(current)}\0`);
|
|
2070
2097
|
return;
|
|
2071
2098
|
}
|
|
2072
|
-
digest.update(`other\0${relative}\0
|
|
2099
|
+
digest.update(`other\0${relative}\0`);
|
|
2073
2100
|
}
|
|
2074
2101
|
|
|
2075
2102
|
visit(directory, '');
|
|
@@ -2096,15 +2123,18 @@ function installSkill(request) {
|
|
|
2096
2123
|
fail(`bundled ${SKILL_NAME} skill is missing from this DriftSeal installation: ${sourceDir}`);
|
|
2097
2124
|
}
|
|
2098
2125
|
|
|
2099
|
-
const sourceDigest =
|
|
2100
|
-
const existingDigest =
|
|
2126
|
+
const sourceDigest = skillTreeDigest(sourceDir);
|
|
2127
|
+
const existingDigest = skillTreeDigest(skillDir);
|
|
2101
2128
|
if (existingDigest === sourceDigest) {
|
|
2102
2129
|
printLine(`${SKILL_NAME} skill is already installed for ${targetLabel} (${scope}): ${skillDir}`);
|
|
2103
2130
|
return { changed: false, target, scope, root, skillDir };
|
|
2104
2131
|
}
|
|
2105
|
-
|
|
2132
|
+
// An untouched skill from an earlier DriftSeal upgrades on its own; only a
|
|
2133
|
+
// skill this installer never wrote needs the operator to confirm with --force.
|
|
2134
|
+
const upgraded = existingDigest !== null && SKILL_RELEASE_DIGESTS.has(existingDigest);
|
|
2135
|
+
if (existingDigest !== null && !upgraded && !force) {
|
|
2106
2136
|
fail(
|
|
2107
|
-
`${targetLabel} already has a
|
|
2137
|
+
`${targetLabel} already has a ${SKILL_NAME} skill DriftSeal did not install at ${skillDir}; ` +
|
|
2108
2138
|
're-run with --force to replace it'
|
|
2109
2139
|
);
|
|
2110
2140
|
}
|
|
@@ -2134,9 +2164,12 @@ function installSkill(request) {
|
|
|
2134
2164
|
throw err;
|
|
2135
2165
|
}
|
|
2136
2166
|
|
|
2137
|
-
printLine(
|
|
2167
|
+
printLine(
|
|
2168
|
+
`${upgraded ? 'Upgraded' : 'Installed'} ${SKILL_NAME} skill for ` +
|
|
2169
|
+
`${targetLabel} (${scope}): ${skillDir}`
|
|
2170
|
+
);
|
|
2138
2171
|
if (scope === 'project') printLine(`Repository root: ${root}`);
|
|
2139
|
-
return { changed: true, target, scope, root, skillDir };
|
|
2172
|
+
return { changed: true, upgraded, target, scope, root, skillDir };
|
|
2140
2173
|
}
|
|
2141
2174
|
|
|
2142
2175
|
const HOOK_TARGETS = ['kimi-code', 'claude-code', 'codex'];
|