runlist 0.95.0 → 0.95.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/README.md
CHANGED
|
@@ -1115,6 +1115,11 @@ validation, customize rendering and summaries, or react to lifecycle events.
|
|
|
1115
1115
|
Hooks receive the resolved config and command context; mutation hooks participate
|
|
1116
1116
|
in the command's dry-run and failure contracts.
|
|
1117
1117
|
|
|
1118
|
+
## Development checks
|
|
1119
|
+
|
|
1120
|
+
See [VERIFYING.md](VERIFYING.md) for local checks, qualified Git toolchains,
|
|
1121
|
+
and the explicit compatibility and desktop qualification workflows.
|
|
1122
|
+
|
|
1118
1123
|
## License
|
|
1119
1124
|
|
|
1120
1125
|
MIT
|
package/package.json
CHANGED
package/src/app-git-commits.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import {gitEnvironment} from './app-git.mjs';
|
|
|
7
7
|
import {commitStore,uuid,fail,hash} from './git-commit-store.mjs';
|
|
8
8
|
import {run} from './git-commit-protocol.mjs';
|
|
9
9
|
import {currentProcessOwner,processStartIdentity,processOwnerLiveness} from './atomic-mutation.mjs';
|
|
10
|
+
import {requestCommitCancellation} from './git-commit-cancellation.mjs';
|
|
10
11
|
// Jobs survive renderer/helper disconnect; no operation ID is ever replayed.
|
|
11
12
|
const children=new Map();
|
|
12
13
|
function stopped(r){if(!r.workerOwner)return r.state==='reviewed'||r.state==='failed';if(processOwnerLiveness(r.workerOwner)!=='dead')return false;try{process.kill(-r.workerOwner.pid,0);return false;}catch(e){return e.code==='ESRCH';}}
|
|
@@ -42,7 +43,7 @@ export function createAppGitCommits({config,actor,authenticate,git}){
|
|
|
42
43
|
function inspect(req,id){identity(req);const r=store.read(id);if(!r)return null;return publicOperation(r,live(r));}
|
|
43
44
|
function start(req,{operationId}){identity(req);platform();storage();return store.exclusive(()=>{const r=store.read(operationId);if(!r)fail('git-operation-missing','Review a local commit first.');if(r.state!=='reviewed'||live(r))return publicOperation(r,live(r));if(Date.now()>r.expiresAt)fail('git-review-expired','This review expired. Review current files again.');if(blocker(operationId))fail('git-operation-active','Another retained Git operation needs inspection first.');return launch(operationId,'execute');});}
|
|
44
45
|
function job(req,{operationId,...request},action){identity(req);platform();storage();return store.exclusive(()=>{const r=store.read(operationId);if(!r)fail('git-operation-missing','The retained Git operation is missing.');if(live(r))fail('git-operation-running','The Git process group is still active or cannot be verified as stopped.');if(r.action==='preview')return publicOperation(r,false);if(action==='settle'){if(typeof request.note!=='string'||!request.note.trim()||request.note.length>4000||!/^[a-f0-9]{64}$/.test(request.expectedIndexRevision??'')||request.expectedRef!==r.observedRef||request.expectedIndexRevision!==r.observedIndex)fail('invalid-request','Acknowledge the current inspected ref/index with a note up to 4,000 characters.');store.update(operationId,d=>{d.settlementRequest={note:request.note.trim(),expectedRef:request.expectedRef,expectedIndexRevision:request.expectedIndexRevision};});}if(r.resolved&&action==='recover')return publicOperation(r,false);return launch(operationId,action);});}
|
|
45
|
-
function cancel(req,{operationId}){identity(req);platform();const r=store.read(operationId);if(!r)fail('git-operation-missing','The retained Git operation is missing.');if(live(r))
|
|
46
|
+
function cancel(req,{operationId}){identity(req);platform();const r=store.read(operationId);if(!r)fail('git-operation-missing','The retained Git operation is missing.');if(live(r))requestCommitCancellation(store,operationId);return publicOperation(store.read(operationId),live(store.read(operationId)));}
|
|
46
47
|
function list(req){identity(req);const items=[];let unavailable=0;try{for(const r of store.all())if(!r.resolved&&(r.state!=='committed'||!r.indexReady))items.push({kind:'git-commit',path:r.rows[0]?.path??r.paths[0],operationId:r.id,state:r.state,at:r.at,available:true});}catch(error){if(error.code==='forbidden')throw error;unavailable++;}return {items,unavailable};}
|
|
47
48
|
return {preview,start,inspect,inspectJob:(req,body)=>job(req,body,'inspect'),recover:(req,body)=>job(req,body,'recover'),cancel,settle:(req,body)=>job(req,body,'settle'),list};
|
|
48
49
|
}
|
package/src/filing.mjs
CHANGED
|
@@ -187,8 +187,13 @@ export function assembleFilingCoverage(docs, config, preparedRows, parentTargets
|
|
|
187
187
|
const [hub, category] = queue[i];
|
|
188
188
|
for (const dependent of dependents.get(hub) ?? []) addCategory(dependent, category);
|
|
189
189
|
}
|
|
190
|
-
for (const rows of homes.values())
|
|
191
|
-
|
|
190
|
+
for (const rows of homes.values()) {
|
|
191
|
+
// Metadata reads can finish in any order. Keep CLI/GUI evidence and home
|
|
192
|
+
// pagination stable by source path and physical line, retaining duplicates.
|
|
193
|
+
rows.sort((a, b) => a.hub < b.hub ? -1 : a.hub > b.hub ? 1 : a.line - b.line);
|
|
194
|
+
for (const row of rows) {
|
|
195
|
+
row.categories = row.category ? [row.category] : [...(hubCategories.get(row.hub) ?? [])].sort();
|
|
196
|
+
}
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
// Parent inheritance is explicit and cycle-safe. A child's own home takes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {processOwnerLiveness} from './atomic-mutation.mjs';
|
|
2
|
+
import {fail} from './git-commit-store.mjs';
|
|
3
|
+
|
|
4
|
+
// A failed signal is never evidence that a worker or its process group stopped.
|
|
5
|
+
// Keep the receipt and let the caller inspect liveness again after the request.
|
|
6
|
+
export function requestCommitCancellation(store,id,{ownerLiveness=processOwnerLiveness,signal=(pid,value)=>process.kill(pid,value)}={}){
|
|
7
|
+
const r=store.read(id);
|
|
8
|
+
if(ownerLiveness(r.workerOwner)!=='live')fail('git-owner-unverified','The worker identity cannot be verified. Keep its receipt and inspect with Git.');
|
|
9
|
+
store.update(id,d=>{d.cancelRequestedAt=new Date().toISOString();});
|
|
10
|
+
try{signal(-r.workerOwner.pid,'SIGKILL');}
|
|
11
|
+
catch(error){if(error.code!=='ESRCH')fail('git-cancel-failed','The Git process group could not be stopped. Keep its receipt and inspect the operation before continuing.');}
|
|
12
|
+
}
|