driftseal 1.3.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -9
- package/README.zh-CN.md +17 -6
- package/bin/driftseal.js +108 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -251,15 +251,32 @@ driftseal end \
|
|
|
251
251
|
|
|
252
252
|
If the scope changes, close the current intent as `partial` or `abandoned`, then start a new one. After context loss, use `driftseal status` and `driftseal log --last 3` to re-anchor.
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
254
|
+
Record an intent for changes intended to persist in the project: edits to code,
|
|
255
|
+
configuration, documentation, dependencies, and equivalent project files. The
|
|
256
|
+
boundary does not depend on Git: inside a worktree it includes content intended
|
|
257
|
+
for commit, while outside Git it includes durable project files. Everything else
|
|
258
|
+
is exempt. Git operations are entirely outside the intent log because Git
|
|
259
|
+
maintains their history; inspection, branch and worktree management, staging,
|
|
260
|
+
commits, merges, rebases, cherry-picks, tags, and pushes never need an intent of
|
|
261
|
+
their own, though they still require normal authorization and safety checks.
|
|
262
|
+
Single-step builds and checks, such as compiling or running tests, need no
|
|
263
|
+
intent. Auxiliary file or shell operations whose results remain outside durable
|
|
264
|
+
project content — an `rsync` scratch copy, temp scaffolding — need none either.
|
|
265
|
+
State changes to a remote machine or the local environment are also exempt when
|
|
266
|
+
they do not write durable project content into this workspace. When an external
|
|
267
|
+
operation does bring durable content into the project, record the intent for
|
|
268
|
+
that project-content change, not for the external operation itself.
|
|
269
|
+
|
|
270
|
+
In multi-agent work the scope belongs to the worktree, not the writer. One
|
|
271
|
+
worktree holds one open intent; every agent or subagent changing durable project
|
|
272
|
+
content there re-anchors and continues that matching intent. Agents in separate
|
|
273
|
+
worktrees hold separate intents. A configured project root outside Git follows
|
|
274
|
+
the same single-intent rule. An agent that only receives another agent's changes
|
|
275
|
+
through Git or into a shared worktree records no receiving intent and lets
|
|
276
|
+
`verify` expose misalignment. Handoff files are exempt while ignored or
|
|
277
|
+
otherwise kept outside durable project content and require an intent when
|
|
278
|
+
promoted into it. Taking over work in the same root is a re-anchor, not a
|
|
279
|
+
boundary: resume the open intent when its objective still matches the task.
|
|
263
280
|
|
|
264
281
|
## Commands
|
|
265
282
|
|
package/README.zh-CN.md
CHANGED
|
@@ -235,12 +235,23 @@ driftseal end \
|
|
|
235
235
|
|
|
236
236
|
如果范围发生变化,先把当前 intent 以 `partial` 或 `abandoned` 关闭,再开启新的 intent。发生 context loss 后,用 `driftseal status` 和 `driftseal log --last 3` 重新锚定当前目标。
|
|
237
237
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
intent
|
|
243
|
-
|
|
238
|
+
需要记录 intent 的是准备作为项目内容长期保留的改动,包括代码、配置、文档、依赖及同类
|
|
239
|
+
项目文件。这个边界不取决于 Git:在 worktree 中,它包括准备提交的内容;在非 Git 项目中,
|
|
240
|
+
它包括要长期保留的项目文件。其余操作一律免记。Git 会自行维护操作历史,因此查看状态、
|
|
241
|
+
管理 branch 或 worktree、stage、commit、merge、rebase、cherry-pick、tag 和 push 都
|
|
242
|
+
不需要单独开启 intent,但仍须遵守正常的授权与安全要求。编译、跑测试等单步构建或检查也
|
|
243
|
+
不需要 intent。结果不会成为持久项目内容的辅助文件或 shell 操作——比如 `rsync` 临时拷贝、
|
|
244
|
+
临时脚手架——同样免记。远程机器或本机环境的状态变更,只要不把持久项目内容写入当前
|
|
245
|
+
workspace,也不属于 intent log;如果外部操作确实把持久内容带进项目,记录的是落入项目的
|
|
246
|
+
内容改动,而不是外部操作本身。
|
|
247
|
+
|
|
248
|
+
多 agent 协作时,intent 的作用域属于 worktree,而不是写入者。一个 worktree 只能有一个
|
|
249
|
+
open intent;在那里改动持久项目内容的所有 agent 和 subagent 都要先重新锚定,再继续同一个
|
|
250
|
+
匹配的 intent。不同 worktree 各自持有 intent;非 Git 项目的 configured root 同样只持有
|
|
251
|
+
一个。只通过 Git 或共享 worktree 接收其他 agent 变更的一方不另记 receiving intent,交给
|
|
252
|
+
`verify` 暴露不一致。handoff 文件在被 ignore 或以其他方式排除在持久项目内容之外时免记,
|
|
253
|
+
一旦转为正式项目内容就需要 intent。在同一个 root 中途接手工作属于重新锚定而非边界:目标
|
|
254
|
+
仍然匹配就继续沿用 open intent。
|
|
244
255
|
|
|
245
256
|
## 命令速览
|
|
246
257
|
|
package/bin/driftseal.js
CHANGED
|
@@ -41,7 +41,7 @@ const DECISION_STATUSES = [
|
|
|
41
41
|
'superseded',
|
|
42
42
|
];
|
|
43
43
|
const EVENT_SCHEMA_VERSION = 4;
|
|
44
|
-
const PROTOCOL_VERSION =
|
|
44
|
+
const PROTOCOL_VERSION = 14;
|
|
45
45
|
const DEFAULT_LOG_LANGUAGE = 'en';
|
|
46
46
|
const IN_PROGRESS_GIT_PATH = 'driftseal-in-progress.jsonl';
|
|
47
47
|
const LOCK_STALE_MS = 30 * 60 * 1000;
|
|
@@ -1874,20 +1874,31 @@ MCP and lifecycle hooks are optional adapters.
|
|
|
1874
1874
|
|
|
1875
1875
|
${intentLogLanguageParagraph(language)}
|
|
1876
1876
|
|
|
1877
|
-
1. **Write intent first**, before
|
|
1878
|
-
making any other non-Git change that may need a rollback:
|
|
1877
|
+
1. **Write intent first**, before changing durable project content:
|
|
1879
1878
|
\`driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"\`.
|
|
1880
1879
|
Repeat \`--accept\` when completion has multiple independently observable criteria.
|
|
1881
1880
|
Add one \`--decision <id>\` for each existing decision this round may change.
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1881
|
+
Record intents for changes intended to persist in the project: edits to code,
|
|
1882
|
+
configuration, documentation, dependencies, and equivalent project files,
|
|
1883
|
+
whether or not the project is inside a Git worktree. Everything else is
|
|
1884
|
+
exempt: Git operations (Git maintains their history — inspection, branch
|
|
1885
|
+
and worktree management, staging, commits, merges, rebases, cherry-picks,
|
|
1886
|
+
tags, and pushes); single-step commands that only build or check work
|
|
1887
|
+
already done, such as compiling or running tests; auxiliary file or shell
|
|
1888
|
+
operations whose results remain outside durable project content (for example
|
|
1889
|
+
an rsync scratch copy or temp scaffolding); and state changes to a remote
|
|
1890
|
+
machine or the local environment that do not write durable project content
|
|
1891
|
+
into this workspace. When an external operation does bring durable content
|
|
1892
|
+
into the project, record an intent for that project-content change, not for
|
|
1893
|
+
the external operation itself.
|
|
1894
|
+
In multi-agent work, one open intent belongs to one worktree, or to one
|
|
1895
|
+
configured project root outside Git. Every agent or subagent that changes
|
|
1896
|
+
durable project content in the same root first re-anchors and continues its
|
|
1897
|
+
matching open intent; agents working in separate worktrees hold separate
|
|
1898
|
+
intents. An agent that only receives another agent's changes through Git or
|
|
1899
|
+
into a shared worktree records no receiving intent and lets \`verify\` expose
|
|
1900
|
+
misalignment; handoff files are exempt while ignored or otherwise kept
|
|
1901
|
+
outside durable project content and require an intent when promoted into it.
|
|
1891
1902
|
Size an intent to the smallest unit that leaves the tree self-consistent
|
|
1892
1903
|
and can be verified on its own.
|
|
1893
1904
|
2. **Execute only the intent.** Scope change? Close the current intent
|
|
@@ -1914,12 +1925,15 @@ ${intentLogLanguageParagraph(language)}
|
|
|
1914
1925
|
by the next linked \`decision update\` or successful \`end\`. Closing as
|
|
1915
1926
|
\`failed\` or \`abandoned\` cancels pending recovery for that intent.
|
|
1916
1927
|
Git operations remain subject to normal authorization and safety requirements
|
|
1917
|
-
even though they do not require an intent. Any
|
|
1918
|
-
preparing a Git operation
|
|
1928
|
+
even though they do not require an intent. Any content change made while
|
|
1929
|
+
preparing a Git operation still requires an intent when it meets the
|
|
1930
|
+
durable-project-content rule in step 1.
|
|
1919
1931
|
4. **Re-anchor after context loss**: run \`driftseal status\` and \`driftseal log --last 3\` before
|
|
1920
1932
|
doing anything else. The open intent is the source of truth: resume it when its
|
|
1921
1933
|
objective still matches the current task; otherwise close it (\`partial\` or
|
|
1922
|
-
\`abandoned\`, with a note) and \`begin\` a new one.
|
|
1934
|
+
\`abandoned\`, with a note) and \`begin\` a new one. Taking over work in the
|
|
1935
|
+
same root from another agent is the same re-anchor: resume the open intent
|
|
1936
|
+
when its objective still matches.
|
|
1923
1937
|
|
|
1924
1938
|
**Log access goes only through DriftSeal.** Never read, edit, move, or delete
|
|
1925
1939
|
\`.intent-log/events.jsonl\` (or anything under \`$DRIFTSEAL_HOME\`) directly; use
|
|
@@ -1935,7 +1949,75 @@ ${INTENT_PROTOCOL_END}`;
|
|
|
1935
1949
|
}
|
|
1936
1950
|
|
|
1937
1951
|
function previousIntentProtocolBlock(version, language = DEFAULT_LOG_LANGUAGE, localLog = false) {
|
|
1938
|
-
const
|
|
1952
|
+
const v13 = intentProtocolBlock(version, language, localLog)
|
|
1953
|
+
.replace(
|
|
1954
|
+
'1. **Write intent first**, before changing durable project content:\n' +
|
|
1955
|
+
' `driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"`.\n' +
|
|
1956
|
+
' Repeat `--accept` when completion has multiple independently observable criteria.\n' +
|
|
1957
|
+
' Add one `--decision <id>` for each existing decision this round may change.\n' +
|
|
1958
|
+
' Record intents for changes intended to persist in the project: edits to code,\n' +
|
|
1959
|
+
' configuration, documentation, dependencies, and equivalent project files,\n' +
|
|
1960
|
+
' whether or not the project is inside a Git worktree. Everything else is\n' +
|
|
1961
|
+
' exempt: Git operations (Git maintains their history — inspection, branch\n' +
|
|
1962
|
+
' and worktree management, staging, commits, merges, rebases, cherry-picks,\n' +
|
|
1963
|
+
' tags, and pushes); single-step commands that only build or check work\n' +
|
|
1964
|
+
' already done, such as compiling or running tests; auxiliary file or shell\n' +
|
|
1965
|
+
' operations whose results remain outside durable project content (for example\n' +
|
|
1966
|
+
' an rsync scratch copy or temp scaffolding); and state changes to a remote\n' +
|
|
1967
|
+
' machine or the local environment that do not write durable project content\n' +
|
|
1968
|
+
' into this workspace. When an external operation does bring durable content\n' +
|
|
1969
|
+
' into the project, record an intent for that project-content change, not for\n' +
|
|
1970
|
+
' the external operation itself.\n' +
|
|
1971
|
+
' In multi-agent work, one open intent belongs to one worktree, or to one\n' +
|
|
1972
|
+
' configured project root outside Git. Every agent or subagent that changes\n' +
|
|
1973
|
+
' durable project content in the same root first re-anchors and continues its\n' +
|
|
1974
|
+
' matching open intent; agents working in separate worktrees hold separate\n' +
|
|
1975
|
+
" intents. An agent that only receives another agent's changes through Git or\n" +
|
|
1976
|
+
' into a shared worktree records no receiving intent and lets `verify` expose\n' +
|
|
1977
|
+
' misalignment; handoff files are exempt while ignored or otherwise kept\n' +
|
|
1978
|
+
' outside durable project content and require an intent when promoted into it.\n' +
|
|
1979
|
+
' Size an intent to the smallest unit that leaves the tree self-consistent\n' +
|
|
1980
|
+
' and can be verified on its own.',
|
|
1981
|
+
'1. **Write intent first**, before modifying, creating, or deleting files, or\n' +
|
|
1982
|
+
' making any other non-Git change that may need a rollback:\n' +
|
|
1983
|
+
' `driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"`.\n' +
|
|
1984
|
+
' Repeat `--accept` when completion has multiple independently observable criteria.\n' +
|
|
1985
|
+
' Add one `--decision <id>` for each existing decision this round may change.\n' +
|
|
1986
|
+
' Git operations never need an intent and are not included in the intent log;\n' +
|
|
1987
|
+
' Git maintains their history. This includes inspection, branch and worktree\n' +
|
|
1988
|
+
' management, staging, commits, merges, rebases, cherry-picks, tags, and pushes.\n' +
|
|
1989
|
+
' A command whose result can be reconstructed from Git state (for example a\n' +
|
|
1990
|
+
' patch file regenerated from a commit range, or a scratch harness that\n' +
|
|
1991
|
+
' re-runs) needs no intent; content that will be committed and cannot be\n' +
|
|
1992
|
+
' reconstructed (for example a .gitignore edit) does.\n' +
|
|
1993
|
+
' Single-step commands that only build or check work already done, such as\n' +
|
|
1994
|
+
' compiling or running tests, also need no intent.\n' +
|
|
1995
|
+
' Size an intent to the smallest unit that leaves the tree self-consistent\n' +
|
|
1996
|
+
' and can be verified on its own.'
|
|
1997
|
+
)
|
|
1998
|
+
.replace(
|
|
1999
|
+
' Git operations remain subject to normal authorization and safety requirements\n' +
|
|
2000
|
+
' even though they do not require an intent. Any content change made while\n' +
|
|
2001
|
+
' preparing a Git operation still requires an intent when it meets the\n' +
|
|
2002
|
+
' durable-project-content rule in step 1.',
|
|
2003
|
+
' Git operations remain subject to normal authorization and safety requirements\n' +
|
|
2004
|
+
' even though they do not require an intent. Any non-Git content change made while\n' +
|
|
2005
|
+
' preparing a Git operation does require a new intent, per the step 1 test.'
|
|
2006
|
+
)
|
|
2007
|
+
.replace(
|
|
2008
|
+
'4. **Re-anchor after context loss**: run `driftseal status` and `driftseal log --last 3` before\n' +
|
|
2009
|
+
' doing anything else. The open intent is the source of truth: resume it when its\n' +
|
|
2010
|
+
' objective still matches the current task; otherwise close it (`partial` or\n' +
|
|
2011
|
+
' `abandoned`, with a note) and `begin` a new one. Taking over work in the\n' +
|
|
2012
|
+
' same root from another agent is the same re-anchor: resume the open intent\n' +
|
|
2013
|
+
' when its objective still matches.',
|
|
2014
|
+
'4. **Re-anchor after context loss**: run `driftseal status` and `driftseal log --last 3` before\n' +
|
|
2015
|
+
' doing anything else. The open intent is the source of truth: resume it when its\n' +
|
|
2016
|
+
' objective still matches the current task; otherwise close it (`partial` or\n' +
|
|
2017
|
+
' `abandoned`, with a note) and `begin` a new one.'
|
|
2018
|
+
);
|
|
2019
|
+
if (version >= 13) return v13;
|
|
2020
|
+
const v12 = v13
|
|
1939
2021
|
.replace(
|
|
1940
2022
|
' `driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"`.\n' +
|
|
1941
2023
|
' Repeat `--accept` when completion has multiple independently observable criteria.',
|
|
@@ -2900,11 +2982,13 @@ function hookReminder(event, { readOnly = false } = {}) {
|
|
|
2900
2982
|
if (!file) return null;
|
|
2901
2983
|
if (event === 'prompt') {
|
|
2902
2984
|
return (
|
|
2903
|
-
'DriftSeal reminder: if this round will
|
|
2904
|
-
'
|
|
2985
|
+
'DriftSeal reminder: if this round will change durable project content in this workspace ' +
|
|
2986
|
+
'(code, configuration, documentation, dependencies), ' +
|
|
2987
|
+
'begin an intent first: driftseal begin "<intent>" --accept "<observable outcome>" ' +
|
|
2905
2988
|
'--verify "<command>". ' +
|
|
2906
|
-
'Questions, read-only exploration,
|
|
2907
|
-
'
|
|
2989
|
+
'Questions, read-only exploration, single-step checks, temporary work outside durable ' +
|
|
2990
|
+
'project content, and external state changes that do not write project content here need ' +
|
|
2991
|
+
'no intent — skip this reminder when it does not apply.'
|
|
2908
2992
|
);
|
|
2909
2993
|
}
|
|
2910
2994
|
const open = openIntent(fold(readEvents({ file, readOnly })));
|
|
@@ -4607,6 +4691,8 @@ const commands = {
|
|
|
4607
4691
|
knownManagedBlocks: [
|
|
4608
4692
|
...sourceLanguages.flatMap((source) => [
|
|
4609
4693
|
protocolEol(intentProtocolBlock(PROTOCOL_VERSION, source), eol),
|
|
4694
|
+
protocolEol(previousIntentProtocolBlock(13, source), eol),
|
|
4695
|
+
protocolEol(previousIntentProtocolBlock(13, source, true), eol),
|
|
4610
4696
|
protocolEol(previousIntentProtocolBlock(12, source), eol),
|
|
4611
4697
|
protocolEol(previousIntentProtocolBlock(12, source, true), eol),
|
|
4612
4698
|
protocolEol(previousIntentProtocolBlock(11, source), eol),
|
|
@@ -4634,6 +4720,8 @@ const commands = {
|
|
|
4634
4720
|
knownManagedBlocks: [
|
|
4635
4721
|
...sourceLanguages.flatMap((source) => [
|
|
4636
4722
|
protocolEol(decisionProtocolBlock(PROTOCOL_VERSION, source), eol),
|
|
4723
|
+
protocolEol(previousDecisionProtocolBlock(13, source), eol),
|
|
4724
|
+
protocolEol(previousDecisionProtocolBlock(13, source, true), eol),
|
|
4637
4725
|
protocolEol(previousDecisionProtocolBlock(12, source), eol),
|
|
4638
4726
|
protocolEol(previousDecisionProtocolBlock(12, source, true), eol),
|
|
4639
4727
|
protocolEol(previousDecisionProtocolBlock(11, source), eol),
|