@klarkxy/dsh-git-commit 0.2.5 → 0.3.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 CHANGED
@@ -27,6 +27,7 @@ If the model list cannot load, or some providers fail, use **Retry** beside the
27
27
 
28
28
  ## Good to know
29
29
 
30
+ - The repository follows the conversation's current working directory. Changing directories while a commit is being planned stops the run.
30
31
  - All uncommitted changes in the repository are included, including new files.
31
32
  - It only commits; it never pushes.
32
33
  - If the run stops partway, finished commits stay and the panel shows what was left. Nothing is rolled back or retried automatically.
@@ -27,6 +27,7 @@ dsh plugin --profile web add @klarkxy/dsh-git-commit
27
27
 
28
28
  ## 注意
29
29
 
30
+ - 仓库跟随对话当前的工作目录;规划提交期间切换目录会停止本次提交。
30
31
  - 会提交仓库里的全部未提交改动,包括新文件。
31
32
  - 只提交,不推送。
32
33
  - 中途停止时,已完成的提交会保留,面板显示剩余内容;不会自动回滚或重试。
@@ -1358,25 +1358,18 @@ ${scope} {
1358
1358
  }
1359
1359
  //#endregion
1360
1360
  //#region ../dsh-plugin-kit/src/contracts.ts
1361
- /**
1362
- * Remote contribution for model-settings change notifications.
1363
- * Provided by `@klarkxy/dsh-model-hub` (`ModelSettingsChangesController`);
1364
- * subscribers degrade silently when that package is not installed.
1365
- * The stream carries invalidations only — `ready` is never a settings snapshot.
1366
- */
1367
- const MODEL_SETTINGS_CHANGES_REMOTE = {
1368
- package: "@klarkxy/dsh-model-hub",
1369
- descriptors: [{
1370
- id: "modelSettingsChanges/watch",
1371
- service: "modelSettingsChangesController",
1372
- namespace: "modelSettingsChanges",
1373
- method: "watch",
1374
- mode: "stream",
1375
- invocation: { kind: "direct" },
1376
- parameters: [],
1377
- cancellation: { parameter: "signal" }
1378
- }]
1379
- };
1361
+ /** `@klarkxy/dsh-git-commit` becomes `KlarkxyDshGitCommitModelSettingsChanges`. */
1362
+ function modelSettingsChangesIdentity(packageName) {
1363
+ const scoped = /^@([^/]+)\/(.+)$/.exec(packageName);
1364
+ const parts = (scoped ? `${scoped[1]}/${scoped[2]}` : packageName).split(/[^A-Za-z0-9]+/).filter(Boolean);
1365
+ if (!parts.length) throw new Error("Model settings package name has no RPC segment");
1366
+ const segment = `${parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}ModelSettingsChanges`;
1367
+ if (!/^[A-Z][A-Za-z0-9]*$/.test(segment)) throw new Error(`Model settings sync name is not an RPC segment: ${segment}`);
1368
+ return {
1369
+ service: segment,
1370
+ namespace: segment
1371
+ };
1372
+ }
1380
1373
  //#endregion
1381
1374
  //#region ../dsh-plugin-kit/src/model-settings-client.ts
1382
1375
  /** This stream carries invalidations only; ready is never a settings snapshot. */
@@ -1391,17 +1384,44 @@ function parseModelSettingsChangeFrame(value) {
1391
1384
  };
1392
1385
  throw new Error("Invalid model settings change frame");
1393
1386
  }
1394
- MODEL_SETTINGS_CHANGES_REMOTE.package, MODEL_SETTINGS_CHANGES_REMOTE.descriptors.map((descriptor) => ({
1395
- ...descriptor,
1396
- result: {
1397
- mode: "strict",
1398
- typeSymbol: "ModelSettings.ChangeFrame",
1399
- create: () => ({ parse: parseModelSettingsChangeFrame })
1400
- }
1401
- }));
1387
+ /** One owner's contribution. Each package mounts only its own endpoint. */
1388
+ function modelSettingsChangesRemote(packageName, identity = modelSettingsChangesIdentity(packageName)) {
1389
+ return {
1390
+ package: packageName,
1391
+ descriptors: [{
1392
+ id: `${identity.namespace}/watch`,
1393
+ service: identity.service,
1394
+ namespace: identity.namespace,
1395
+ method: "watch",
1396
+ mode: "stream",
1397
+ invocation: { kind: "direct" },
1398
+ parameters: [],
1399
+ cancellation: { parameter: "signal" },
1400
+ result: {
1401
+ mode: "strict",
1402
+ typeSymbol: "ModelSettings.ChangeFrame",
1403
+ create: () => ({ parse: parseModelSettingsChangeFrame })
1404
+ }
1405
+ }]
1406
+ };
1407
+ }
1408
+ /** Mount from a synchronous apply. Disposal waits for an in-flight mount and
1409
+ * then withdraws it, so the contribution cannot outlive the plugin. */
1410
+ function mountModelSettingsChanges(ctx, packageName) {
1411
+ const contribution = modelSettingsChangesRemote(packageName);
1412
+ ctx.inject(["remote"], (injected) => {
1413
+ const scope = injected;
1414
+ const mounting = scope.remote.$mount(contribution);
1415
+ mounting.catch(() => {});
1416
+ scope.effect(() => async () => {
1417
+ await (await mounting.catch(() => void 0))?.();
1418
+ });
1419
+ });
1420
+ }
1402
1421
  /** Native RemoteStream owns carrier reconnects; no timers or browser transport.
1403
1422
  * A factory shares one logical stream while at least one subscriber remains. */
1404
- function createModelSettingsSubscriber(ctx, namespace) {
1423
+ function createModelSettingsSubscriber(ctx, packageName, identity = modelSettingsChangesIdentity(packageName), accept = (ns) => ns === packageName) {
1424
+ const endpoint = identity;
1405
1425
  const listeners = /* @__PURE__ */ new Set();
1406
1426
  let injection;
1407
1427
  let current;
@@ -1427,12 +1447,18 @@ function createModelSettingsSubscriber(ctx, namespace) {
1427
1447
  };
1428
1448
  const start = () => {
1429
1449
  const life = ++lifecycle;
1430
- injection = ctx.inject(["remote", "remote.modelSettingsChanges"], (injected) => {
1450
+ injection = ctx.inject(["remote", `remote.${endpoint.namespace}`], (injected) => {
1431
1451
  if (life !== lifecycle || !listeners.size) return;
1432
1452
  const scope = injected;
1453
+ const service = scope.remote[endpoint.namespace];
1454
+ if (!service || !("watch" in service) || !service.watch) {
1455
+ report("Model settings sync service unavailable");
1456
+ return;
1457
+ }
1458
+ const watch = service.watch;
1433
1459
  const stream = scope.remote.$stream({
1434
1460
  name: "Model settings sync",
1435
- open: (signal) => scope.remote.modelSettingsChanges.watch(signal),
1461
+ open: (signal) => watch(signal),
1436
1462
  ended: (accepted) => /* @__PURE__ */ new Error(`Model settings sync stream ended ${accepted ? "after" : "before"} ready; refresh or reopen the page`)
1437
1463
  });
1438
1464
  const session = {
@@ -1467,7 +1493,7 @@ function createModelSettingsSubscriber(ctx, namespace) {
1467
1493
  invalidate();
1468
1494
  } else {
1469
1495
  if (!ready) throw new Error("Model settings sync change arrived before ready");
1470
- if (namespace === "*" || frame.ns === namespace) invalidate();
1496
+ if (accept(frame.ns)) invalidate();
1471
1497
  }
1472
1498
  }
1473
1499
  } catch (error) {
@@ -2339,6 +2365,7 @@ function GitCommitSettingsPanel(props) {
2339
2365
  }
2340
2366
  function apply(ctx) {
2341
2367
  const client = ctx;
2368
+ mountModelSettingsChanges(ctx, PLUGIN_NAME);
2342
2369
  const settingsSubscriber = createModelSettingsSubscriber(ctx, PLUGIN_NAME);
2343
2370
  const subscribeSettings = (change, error) => settingsSubscriber.subscribe(change, error);
2344
2371
  ctx.provide(GIT_COMMIT_CLIENT_SERVICE, { active: true });