gutterpress 0.11.6 → 0.11.7-alpha.2

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.
@@ -48,7 +48,7 @@ export { listProjectStyles, resolveActiveStyles } from "../lib/style-resolver.ts
48
48
  export type { ProjectStyle } from "../lib/style-resolver.ts";
49
49
  export { readManifestFields, setManifestFields, setActiveStyles, } from "../lib/manifest-config.ts";
50
50
  export type { ProjectConfigFields } from "../lib/manifest-config.ts";
51
- export { providerFor, restoreVersionWithBackup, isNoChangesError, countUnversionedChanges, AUTO_SNAPSHOT_MESSAGE, RESTORE_BACKUP_MESSAGE, HISTORY_PAGE_LIMIT, listLocalBranches, switchBranch, SWITCH_BRANCH_SNAPSHOT_MESSAGE, } from "../lib/source-provider.ts";
51
+ export { providerFor, restoreVersionWithBackup, isNoChangesError, countUnversionedChanges, whenGitIdle, AUTO_SNAPSHOT_MESSAGE, RESTORE_BACKUP_MESSAGE, HISTORY_PAGE_LIMIT, listLocalBranches, switchBranch, SWITCH_BRANCH_SNAPSHOT_MESSAGE, } from "../lib/source-provider.ts";
52
52
  export type { ListHistoryOptions, HistoryPage, UnversionedChanges, LocalBranches, SwitchBranchOptions, SwitchBranchResult, } from "../lib/source-provider.ts";
53
53
  export { autoSnapshotDelayMs, autoSyncDelayMs, isGitInternalPath, AUTO_SNAPSHOT_DEFAULT_MINUTES, AUTO_SYNC_MIN_MINUTES, AUTO_SYNC_MAX_MINUTES, AUTO_SYNC_DEFAULT_MINUTES, AUTO_SYNC_PUSH_INTERVAL_MINUTES, } from "../lib/host-policy.ts";
54
54
  export type { AutoSnapshotPolicy, AutoSyncPolicy, } from "../lib/host-policy.ts";
package/dist/api/index.js CHANGED
@@ -122,7 +122,7 @@ import {
122
122
  syncProject,
123
123
  testRemoteAccess,
124
124
  validateProjectExtensions
125
- } from "../index-yzcd0ezr.js";
125
+ } from "../index-96fk7fjk.js";
126
126
  import {
127
127
  BuildError,
128
128
  DEFAULT_PRINT_OPTS,
@@ -142,8 +142,9 @@ import {
142
142
  providerFor,
143
143
  resolveLogger,
144
144
  restoreVersionWithBackup,
145
- switchBranch
146
- } from "../index-7mqst9tg.js";
145
+ switchBranch,
146
+ whenGitIdle
147
+ } from "../index-fnhak0nh.js";
147
148
  import {
148
149
  capabilitiesFor,
149
150
  detectProjectSource,
@@ -153,6 +154,7 @@ import {
153
154
  } from "../index-v5mp7a6q.js";
154
155
  import"../index-37x76zdn.js";
155
156
  export {
157
+ whenGitIdle,
156
158
  validateProjectExtensions,
157
159
  testRemoteAccess,
158
160
  syncProject,
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-02sh3r8x.js";
3
+ } from "./cli-c565qhpe.js";
4
4
  import {
5
5
  log
6
- } from "./cli-emp8wz36.js";
6
+ } from "./cli-43h754g9.js";
7
7
  import {
8
8
  UsageError,
9
9
  rejectExtraPositionals,
10
10
  rejectUnknownFlags
11
- } from "./cli-1bccnym3.js";
11
+ } from "./cli-kqg2xy7t.js";
12
12
  import"./cli-5vdgncmm.js";
13
13
  import"./cli-c41yr7he.js";
14
14
  import {
15
15
  EXIT_CODES
16
16
  } from "./cli-46ycxe6r.js";
17
- import"./cli-4tx0szk7.js";
17
+ import"./cli-pfczdbyd.js";
18
18
  import"./cli-v5mp7a6q.js";
19
19
  import"./cli-37x76zdn.js";
20
20
 
@@ -1,23 +1,23 @@
1
1
  import {
2
2
  runBuild,
3
3
  splitOutPath
4
- } from "./cli-02sh3r8x.js";
4
+ } from "./cli-c565qhpe.js";
5
5
  import {
6
6
  log
7
- } from "./cli-emp8wz36.js";
7
+ } from "./cli-43h754g9.js";
8
8
  import {
9
9
  UsageError,
10
10
  parseFormat,
11
11
  parsePdfxFlavor,
12
12
  rejectExtraPositionals,
13
13
  rejectUnknownFlags
14
- } from "./cli-1bccnym3.js";
14
+ } from "./cli-kqg2xy7t.js";
15
15
  import"./cli-5vdgncmm.js";
16
16
  import"./cli-c41yr7he.js";
17
17
  import {
18
18
  BuildError
19
19
  } from "./cli-46ycxe6r.js";
20
- import"./cli-4tx0szk7.js";
20
+ import"./cli-pfczdbyd.js";
21
21
  import"./cli-v5mp7a6q.js";
22
22
  import"./cli-37x76zdn.js";
23
23
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "./cli-1bccnym3.js";
3
+ } from "./cli-kqg2xy7t.js";
4
4
  import {
5
5
  execCapture,
6
6
  findTool,
@@ -13,12 +13,12 @@ import {
13
13
  stampCreator,
14
14
  stripAnnotations,
15
15
  warn
16
- } from "./cli-emp8wz36.js";
16
+ } from "./cli-43h754g9.js";
17
17
  import {
18
18
  DEBOUNCE,
19
19
  UsageError,
20
20
  resolvePort
21
- } from "./cli-1bccnym3.js";
21
+ } from "./cli-kqg2xy7t.js";
22
22
  import {
23
23
  MARGIN_BOX_IGNORED_PROPERTIES,
24
24
  RENDER_TIMEOUT_MS,
@@ -61,7 +61,7 @@ import {
61
61
  vendoredNpmPluginRoot,
62
62
  verifyVendoredPlugin,
63
63
  windowsPathKey
64
- } from "./cli-4tx0szk7.js";
64
+ } from "./cli-pfczdbyd.js";
65
65
  import {
66
66
  detectProjectSource,
67
67
  repoSubPath
@@ -9843,7 +9843,7 @@ async function scaffoldProject(options) {
9843
9843
  let versionHistoryError;
9844
9844
  if (requested === "local-git") {
9845
9845
  try {
9846
- const { providerFor } = await import("./source-provider-gy3cn7kw.js");
9846
+ const { providerFor } = await import("./source-provider-ta09wegv.js");
9847
9847
  const provider = providerFor({ type: "local-folder", path: projectDir });
9848
9848
  await provider.initVersionHistory({
9849
9849
  projectDir,
@@ -4,7 +4,7 @@ import {
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "gutterpress",
7
- version: "0.11.6",
7
+ version: "0.11.7-alpha.2",
8
8
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
9
9
  author: "itlackey",
10
10
  license: "MPL-2.0",
@@ -6,13 +6,37 @@ import {
6
6
 
7
7
  // src/lib/git-fs.ts
8
8
  import * as nodeFs from "node:fs";
9
- var MUTABLE_GIT_METADATA = /(?:^|[\\/])\.git[\\/](?:index|HEAD|packed-refs|refs[\\/].+)$/;
9
+ var ATOMIC_GIT_FILES = /(?:^|[\\/])\.git[\\/](?:index|HEAD|packed-refs|refs[\\/].+|objects[\\/].+)$/;
10
+ var LOOSE_OBJECT = /(?:^|[\\/])\.git[\\/]objects[\\/][0-9a-f]{2}[\\/][0-9a-f]{38}$/;
10
11
  function needsAtomicWrite(file) {
11
- return typeof file === "string" && MUTABLE_GIT_METADATA.test(file);
12
+ return typeof file === "string" && ATOMIC_GIT_FILES.test(file);
12
13
  }
13
14
  var tempCounter = 0;
14
15
  function tempPathFor(file) {
15
- return `${file}.gp${process.pid.toString(36)}-${(tempCounter++).toString(36)}.tmp`;
16
+ const unique = `${process.pid.toString(36)}-${(tempCounter++).toString(36)}`;
17
+ if (/[\\/]\.git[\\/]objects[\\/]/.test(file)) {
18
+ return file.replace(/[^\\/]+$/, `tmp_obj_gp${unique}`);
19
+ }
20
+ return `${file}.gp${unique}.tmp`;
21
+ }
22
+ function notFound(file) {
23
+ return Object.assign(new Error(`ENOENT: no such file or directory, open '${file}'`), {
24
+ code: "ENOENT",
25
+ errno: -2,
26
+ syscall: "open",
27
+ path: file
28
+ });
29
+ }
30
+ function isTornLooseObject(file, data) {
31
+ return typeof file === "string" && data.length === 0 && LOOSE_OBJECT.test(file);
32
+ }
33
+ async function readFilePromise(file, options) {
34
+ const data = await nodeFs.promises.readFile(file, options);
35
+ if (isTornLooseObject(file, data)) {
36
+ await nodeFs.promises.unlink(file).catch(() => {});
37
+ throw notFound(file);
38
+ }
39
+ return data;
16
40
  }
17
41
  function writeFile2(file, data, options, callback) {
18
42
  const cb = typeof options === "function" ? options : callback;
@@ -48,6 +72,7 @@ async function writeFilePromise(file, data, options) {
48
72
  }
49
73
  var promises2 = {
50
74
  ...nodeFs.promises,
75
+ readFile: readFilePromise,
51
76
  writeFile: writeFilePromise
52
77
  };
53
78
  var gitFs = {
@@ -755,6 +780,12 @@ function withRepoLock(projectDir, fn) {
755
780
  });
756
781
  return run;
757
782
  }
783
+ async function whenGitIdle() {
784
+ while (repoQueues.size > 0) {
785
+ await Promise.all(repoQueues.values());
786
+ await Promise.resolve();
787
+ }
788
+ }
758
789
  function __repoLockQueueSizeForTests() {
759
790
  return repoQueues.size;
760
791
  }
@@ -1248,4 +1279,4 @@ async function switchBranch(options) {
1248
1279
  });
1249
1280
  }
1250
1281
 
1251
- export { npmRegistryUrl, PLUGINS_DIR, VENDORED_NPM_DIR, VENDOR_RECEIPT_FILE, VENDOR_RECEIPT_VERSION, isValidNpmPackageName, parseNpmPluginSpec, isExactNpmVersion, vendoredNpmPluginRoot, vendoredNpmPluginPackageDir, packageEntryFormat, assertWindowsSafeRelativePath, windowsPathKey, packageResolutionTargets, resolvePackageEntry, computeVendorTreeDigest, resolveVendoredPluginInstallRoot, verifyVendoredPlugin, gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, countUnversionedChanges, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup, SWITCH_BRANCH_SNAPSHOT_MESSAGE, listLocalBranches, switchBranch };
1282
+ export { npmRegistryUrl, PLUGINS_DIR, VENDORED_NPM_DIR, VENDOR_RECEIPT_FILE, VENDOR_RECEIPT_VERSION, isValidNpmPackageName, parseNpmPluginSpec, isExactNpmVersion, vendoredNpmPluginRoot, vendoredNpmPluginPackageDir, packageEntryFormat, assertWindowsSafeRelativePath, windowsPathKey, packageResolutionTargets, resolvePackageEntry, computeVendorTreeDigest, resolveVendoredPluginInstallRoot, verifyVendoredPlugin, gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, whenGitIdle, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, countUnversionedChanges, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup, SWITCH_BRANCH_SNAPSHOT_MESSAGE, listLocalBranches, switchBranch };
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  UsageError,
7
7
  package_default,
8
8
  rejectUnknownFlags
9
- } from "./cli-1bccnym3.js";
9
+ } from "./cli-kqg2xy7t.js";
10
10
  import {
11
11
  EXIT_CODES
12
12
  } from "./cli-46ycxe6r.js";
@@ -18,16 +18,16 @@ import {
18
18
  import { defineCommand, parseArgs, runMain } from "citty";
19
19
  import { statSync } from "node:fs";
20
20
  var SUBCOMMANDS = {
21
- new: () => import("./new-431dez0g.js").then((m) => m.default),
22
- preview: () => import("./preview-j429jbx1.js").then((m) => m.default),
23
- build: () => import("./build-j0e2hrza.js").then((m) => m.default),
24
- publish: () => import("./publish-hr60t4j2.js").then((m) => m.default),
25
- lint: () => import("./lint-692hba2b.js").then((m) => m.default),
26
- validate: () => import("./validate-g1ckwmnz.js").then((m) => m.default),
27
- audit: () => import("./audit-vbyr2yaa.js").then((m) => m.default),
28
- preflight: () => import("./preflight-9e0xm760.js").then((m) => m.default),
29
- doctor: () => import("./doctor-radk1tcg.js").then((m) => m.default),
30
- ext: () => import("./ext-vtnqbct0.js").then((m) => m.default)
21
+ new: () => import("./new-w6mb8j16.js").then((m) => m.default),
22
+ preview: () => import("./preview-e8z76b3p.js").then((m) => m.default),
23
+ build: () => import("./build-9apshk7v.js").then((m) => m.default),
24
+ publish: () => import("./publish-x6r4j9zf.js").then((m) => m.default),
25
+ lint: () => import("./lint-cwhpkdbn.js").then((m) => m.default),
26
+ validate: () => import("./validate-k1v9799n.js").then((m) => m.default),
27
+ audit: () => import("./audit-jtqyz25s.js").then((m) => m.default),
28
+ preflight: () => import("./preflight-jt4g0g8t.js").then((m) => m.default),
29
+ doctor: () => import("./doctor-hqc8ab4j.js").then((m) => m.default),
30
+ ext: () => import("./ext-nxtdnqp9.js").then((m) => m.default)
31
31
  };
32
32
  var VERSION = package_default.version;
33
33
  var main = defineCommand({
@@ -52,7 +52,7 @@ async function preflightRequiredInvocations(rawArgs) {
52
52
  const [command, ...commandArgs] = rawArgs;
53
53
  try {
54
54
  if (command === "new") {
55
- const { newArgs } = await import("./new-431dez0g.js");
55
+ const { newArgs } = await import("./new-w6mb8j16.js");
56
56
  rejectUnknownFlags(commandArgs, newArgs, "new");
57
57
  const parsed = parseArgs(commandArgs, {
58
58
  ...newArgs,
@@ -64,7 +64,7 @@ async function preflightRequiredInvocations(rawArgs) {
64
64
  return;
65
65
  }
66
66
  if (command === "preflight") {
67
- const { preflightArgs } = await import("./preflight-9e0xm760.js");
67
+ const { preflightArgs } = await import("./preflight-jt4g0g8t.js");
68
68
  rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
69
69
  const parsed = parseArgs(commandArgs, {
70
70
  ...preflightArgs,
@@ -84,7 +84,7 @@ async function preflightRequiredInvocations(rawArgs) {
84
84
  }
85
85
  if (subcommand.startsWith("-"))
86
86
  return;
87
- const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-vtnqbct0.js");
87
+ const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-nxtdnqp9.js");
88
88
  if (!EXT_SUBCOMMANDS.includes(subcommand)) {
89
89
  throw new UsageError(`gutterpress ext: unknown command "${subcommand}"`);
90
90
  }
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getSystemDiagnostics,
3
3
  log
4
- } from "./cli-emp8wz36.js";
4
+ } from "./cli-43h754g9.js";
5
5
  import {
6
6
  UsageError,
7
7
  rejectExtraPositionals,
8
8
  rejectUnknownFlags
9
- } from "./cli-1bccnym3.js";
9
+ } from "./cli-kqg2xy7t.js";
10
10
  import"./cli-c41yr7he.js";
11
11
  import"./cli-46ycxe6r.js";
12
12
  import"./cli-37x76zdn.js";
@@ -10,21 +10,21 @@ import {
10
10
  removeExtension,
11
11
  searchNpmExtensions,
12
12
  setExtensionEnabled
13
- } from "./cli-02sh3r8x.js";
14
- import"./cli-emp8wz36.js";
13
+ } from "./cli-c565qhpe.js";
14
+ import"./cli-43h754g9.js";
15
15
  import {
16
16
  UsageError,
17
17
  exitForUsage,
18
18
  rejectExtraPositionals,
19
19
  rejectUnknownFlags,
20
20
  resolveProjectDir
21
- } from "./cli-1bccnym3.js";
21
+ } from "./cli-kqg2xy7t.js";
22
22
  import"./cli-5vdgncmm.js";
23
23
  import"./cli-c41yr7he.js";
24
24
  import {
25
25
  EXIT_CODES
26
26
  } from "./cli-46ycxe6r.js";
27
- import"./cli-4tx0szk7.js";
27
+ import"./cli-pfczdbyd.js";
28
28
  import"./cli-v5mp7a6q.js";
29
29
  import"./cli-37x76zdn.js";
30
30
 
@@ -50,7 +50,7 @@ import {
50
50
  verifyVendoredPlugin,
51
51
  windowsPathKey,
52
52
  withRepoLock
53
- } from "./index-7mqst9tg.js";
53
+ } from "./index-fnhak0nh.js";
54
54
  import {
55
55
  detectProjectSource,
56
56
  repoSubPath,
@@ -4301,7 +4301,7 @@ import git from "isomorphic-git";
4301
4301
  // package.json
4302
4302
  var package_default = {
4303
4303
  name: "gutterpress",
4304
- version: "0.11.6",
4304
+ version: "0.11.7-alpha.2",
4305
4305
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
4306
4306
  author: "itlackey",
4307
4307
  license: "MPL-2.0",
@@ -10586,7 +10586,7 @@ async function scaffoldProject(options) {
10586
10586
  let versionHistoryError;
10587
10587
  if (requested === "local-git") {
10588
10588
  try {
10589
- const { providerFor } = await import("./source-provider-m5wes47h.js");
10589
+ const { providerFor } = await import("./source-provider-7c2ww3bz.js");
10590
10590
  const provider = providerFor({ type: "local-folder", path: projectDir });
10591
10591
  await provider.initVersionHistory({
10592
10592
  projectDir,
@@ -10678,7 +10678,7 @@ styles:
10678
10678
  let versionHistoryError;
10679
10679
  if (requested === "local-git") {
10680
10680
  try {
10681
- const { providerFor } = await import("./source-provider-m5wes47h.js");
10681
+ const { providerFor } = await import("./source-provider-7c2ww3bz.js");
10682
10682
  const provider = providerFor({ type: "local-folder", path: dir });
10683
10683
  await provider.initVersionHistory({
10684
10684
  projectDir: dir,
@@ -14452,6 +14452,9 @@ function isUnrelatedHistories(e) {
14452
14452
  const msg = e?.message ?? String(e);
14453
14453
  return code === "UnrelatedHistoriesError" || /unrelated histories|no common commits|refusing to merge unrelated/i.test(msg);
14454
14454
  }
14455
+ function isDamagedObjectError(e) {
14456
+ return e instanceof TypeError && /property 'caller' on string|^Attempted to assign to readonly property\.$/.test(e.message);
14457
+ }
14455
14458
  async function historyUnreadable(dir) {
14456
14459
  try {
14457
14460
  const oid = await git6.resolveRef({ fs: gitFs, dir, ref: "HEAD" });
@@ -14662,7 +14665,7 @@ async function syncProject(options) {
14662
14665
  const setupMsg = setupErrorMessage(e);
14663
14666
  if (setupMsg)
14664
14667
  return { status: "error", message: setupMsg, ...base() };
14665
- if (await historyUnreadable(dir)) {
14668
+ if (isDamagedObjectError(e) || await historyUnreadable(dir)) {
14666
14669
  logger.error("sync", "the book's history could not be read");
14667
14670
  return { status: "error", message: MSG_HISTORY_UNREADABLE, ...base() };
14668
14671
  }
@@ -6,13 +6,37 @@ import {
6
6
 
7
7
  // src/lib/git-fs.ts
8
8
  import * as nodeFs from "node:fs";
9
- var MUTABLE_GIT_METADATA = /(?:^|[\\/])\.git[\\/](?:index|HEAD|packed-refs|refs[\\/].+)$/;
9
+ var ATOMIC_GIT_FILES = /(?:^|[\\/])\.git[\\/](?:index|HEAD|packed-refs|refs[\\/].+|objects[\\/].+)$/;
10
+ var LOOSE_OBJECT = /(?:^|[\\/])\.git[\\/]objects[\\/][0-9a-f]{2}[\\/][0-9a-f]{38}$/;
10
11
  function needsAtomicWrite(file) {
11
- return typeof file === "string" && MUTABLE_GIT_METADATA.test(file);
12
+ return typeof file === "string" && ATOMIC_GIT_FILES.test(file);
12
13
  }
13
14
  var tempCounter = 0;
14
15
  function tempPathFor(file) {
15
- return `${file}.gp${process.pid.toString(36)}-${(tempCounter++).toString(36)}.tmp`;
16
+ const unique = `${process.pid.toString(36)}-${(tempCounter++).toString(36)}`;
17
+ if (/[\\/]\.git[\\/]objects[\\/]/.test(file)) {
18
+ return file.replace(/[^\\/]+$/, `tmp_obj_gp${unique}`);
19
+ }
20
+ return `${file}.gp${unique}.tmp`;
21
+ }
22
+ function notFound(file) {
23
+ return Object.assign(new Error(`ENOENT: no such file or directory, open '${file}'`), {
24
+ code: "ENOENT",
25
+ errno: -2,
26
+ syscall: "open",
27
+ path: file
28
+ });
29
+ }
30
+ function isTornLooseObject(file, data) {
31
+ return typeof file === "string" && data.length === 0 && LOOSE_OBJECT.test(file);
32
+ }
33
+ async function readFilePromise(file, options) {
34
+ const data = await nodeFs.promises.readFile(file, options);
35
+ if (isTornLooseObject(file, data)) {
36
+ await nodeFs.promises.unlink(file).catch(() => {});
37
+ throw notFound(file);
38
+ }
39
+ return data;
16
40
  }
17
41
  function writeFile2(file, data, options, callback) {
18
42
  const cb = typeof options === "function" ? options : callback;
@@ -48,6 +72,7 @@ async function writeFilePromise(file, data, options) {
48
72
  }
49
73
  var promises2 = {
50
74
  ...nodeFs.promises,
75
+ readFile: readFilePromise,
51
76
  writeFile: writeFilePromise
52
77
  };
53
78
  var gitFs = {
@@ -806,6 +831,12 @@ function withRepoLock(projectDir, fn) {
806
831
  });
807
832
  return run;
808
833
  }
834
+ async function whenGitIdle() {
835
+ while (repoQueues.size > 0) {
836
+ await Promise.all(repoQueues.values());
837
+ await Promise.resolve();
838
+ }
839
+ }
809
840
  function __repoLockQueueSizeForTests() {
810
841
  return repoQueues.size;
811
842
  }
@@ -1299,4 +1330,4 @@ async function switchBranch(options) {
1299
1330
  });
1300
1331
  }
1301
1332
 
1302
- export { DEFAULT_NPM_REGISTRY, npmRegistryUrl, PLUGINS_DIR, VENDORED_NPM_DIR, VENDOR_RECEIPT_FILE, VENDOR_RECEIPT_VERSION, isValidNpmPackageName, parseNpmPluginSpec, isExactNpmVersion, vendoredNpmPluginRoot, vendoredNpmPluginPackageDir, toPosixPath, packageEntryFormat, assertWindowsSafeRelativePath, windowsPathKey, packageResolutionTargets, resolvePackageEntry, computeVendorTreeDigest, resolveVendoredPluginInstallRoot, verifyVendoredPlugin, gitFs, errorLogData, resolveLogger, gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, countUnversionedChanges, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup, SWITCH_BRANCH_SNAPSHOT_MESSAGE, listLocalBranches, switchBranch };
1333
+ export { DEFAULT_NPM_REGISTRY, npmRegistryUrl, PLUGINS_DIR, VENDORED_NPM_DIR, VENDOR_RECEIPT_FILE, VENDOR_RECEIPT_VERSION, isValidNpmPackageName, parseNpmPluginSpec, isExactNpmVersion, vendoredNpmPluginRoot, vendoredNpmPluginPackageDir, toPosixPath, packageEntryFormat, assertWindowsSafeRelativePath, windowsPathKey, packageResolutionTargets, resolvePackageEntry, computeVendorTreeDigest, resolveVendoredPluginInstallRoot, verifyVendoredPlugin, gitFs, errorLogData, resolveLogger, gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, whenGitIdle, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, countUnversionedChanges, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup, SWITCH_BRANCH_SNAPSHOT_MESSAGE, listLocalBranches, switchBranch };
package/dist/index.js CHANGED
@@ -141,7 +141,7 @@ import {
141
141
  syncProject,
142
142
  testRemoteAccess,
143
143
  validateProjectExtensions
144
- } from "./index-yzcd0ezr.js";
144
+ } from "./index-96fk7fjk.js";
145
145
  import {
146
146
  BUILD_DIAGNOSTIC_CODES
147
147
  } from "./index-yeej2vhs.js";
@@ -164,8 +164,9 @@ import {
164
164
  providerFor,
165
165
  resolveLogger,
166
166
  restoreVersionWithBackup,
167
- switchBranch
168
- } from "./index-7mqst9tg.js";
167
+ switchBranch,
168
+ whenGitIdle
169
+ } from "./index-fnhak0nh.js";
169
170
  import {
170
171
  capabilitiesFor,
171
172
  detectProjectSource,
@@ -251,6 +252,7 @@ async function runLint(opts = {}) {
251
252
  return { ok: true, riskyCount, containmentCount, filesLinted: linted };
252
253
  }
253
254
  export {
255
+ whenGitIdle,
254
256
  validateProjectExtensions,
255
257
  testRemoteAccess,
256
258
  syncProject,
@@ -11,11 +11,20 @@
11
11
  * the write with temp-file + `rename` removes the truncation window entirely
12
12
  * — a reader sees either the old file or the new one, never a torn one.
13
13
  *
14
- * SCOPE. Only git's mutable metadata is redirected. Working-tree files and
15
- * content-addressed objects keep the plain write: objects are written once
16
- * under a hash of their contents (a torn object is a NEW file that simply
17
- * fails to inflate, it never destroys a good one), and the working tree is
18
- * the author's own files, which `rename` semantics would not improve.
14
+ * SCOPE. Git's mutable metadata AND its object store (loose objects and
15
+ * packs) are redirected. Objects were once left on the plain write on the
16
+ * theory that a torn object is a new file that merely fails to inflate — but
17
+ * isomorphic-git never rewrites an object file that already exists
18
+ * (`writeObjectLoose` skips it), and it reads a loose object BEFORE the packs,
19
+ * so one empty object file from a quit mid-write permanently shadows the good
20
+ * copy and fails every later merge with a masked "buffer error" (0.11.6
21
+ * field report). The working tree is the author's own files, which `rename`
22
+ * semantics would not improve, so it keeps the plain write.
23
+ *
24
+ * SELF-HEAL. Repositories damaged before this fix still hold such empty loose
25
+ * objects. A zero-byte loose object carries no data, so `readFile` deletes it
26
+ * and reports it missing: isomorphic-git then falls through to the packs, and
27
+ * the next write of that object can recreate it.
19
28
  *
20
29
  * NOT A DURABILITY BARRIER. There is deliberately no `fsync`: this closes the
21
30
  * PROCESS-DEATH window, where the page cache survives and `rename` is atomic
@@ -27,7 +36,7 @@
27
36
  * `import { gitFs as fs }` is a drop-in for `import * as fs from "node:fs"`.
28
37
  */
29
38
  import * as nodeFs from "node:fs";
30
- /** True when `file` is git metadata that must be replaced, never truncated. */
39
+ /** True when `file` is a git file that must be replaced, never truncated. */
31
40
  export declare function needsAtomicWrite(file: unknown): file is string;
32
41
  /**
33
42
  * `node:fs` with the two writers above swapped in — the object callers import
@@ -108,6 +108,13 @@ export interface SourceProvider {
108
108
  * the SAME queue as snapshot/restore — ADR 0006 D2 requires one per-repo lock.
109
109
  */
110
110
  export declare function withRepoLock<T>(projectDir: string, fn: () => Promise<T>): Promise<T>;
111
+ /**
112
+ * Resolve once NO git operation is queued or running on any repo — including
113
+ * ones chained while waiting. The desktop host awaits this before quitting so
114
+ * an exit snapshot, backup or merge finishes instead of being killed between
115
+ * its object and ref writes. Never rejects.
116
+ */
117
+ export declare function whenGitIdle(): Promise<void>;
111
118
  /**
112
119
  * Test-only: current number of live per-repo lock queues. Lets tests assert the
113
120
  * B4 reclamation actually happens (the map returns to empty once every queued
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  MANIFEST_FILENAMES,
3
3
  runLint
4
- } from "./cli-02sh3r8x.js";
4
+ } from "./cli-c565qhpe.js";
5
5
  import {
6
6
  log
7
- } from "./cli-emp8wz36.js";
7
+ } from "./cli-43h754g9.js";
8
8
  import {
9
9
  UsageError,
10
10
  rejectExtraPositionals,
11
11
  rejectUnknownFlags
12
- } from "./cli-1bccnym3.js";
12
+ } from "./cli-kqg2xy7t.js";
13
13
  import"./cli-5vdgncmm.js";
14
14
  import"./cli-c41yr7he.js";
15
15
  import {
16
16
  EXIT_CODES
17
17
  } from "./cli-46ycxe6r.js";
18
- import"./cli-4tx0szk7.js";
18
+ import"./cli-pfczdbyd.js";
19
19
  import"./cli-v5mp7a6q.js";
20
20
  import"./cli-37x76zdn.js";
21
21
 
@@ -7,15 +7,15 @@ import {
7
7
  TARGET_IDS,
8
8
  scaffoldExtension,
9
9
  scaffoldProject
10
- } from "./cli-02sh3r8x.js";
10
+ } from "./cli-c565qhpe.js";
11
11
  import {
12
12
  resolveGhostscript
13
- } from "./cli-emp8wz36.js";
13
+ } from "./cli-43h754g9.js";
14
14
  import {
15
15
  UsageError,
16
16
  rejectExtraPositionals,
17
17
  rejectUnknownFlags
18
- } from "./cli-1bccnym3.js";
18
+ } from "./cli-kqg2xy7t.js";
19
19
  import"./cli-5vdgncmm.js";
20
20
  import {
21
21
  isToolAvailable
@@ -23,7 +23,7 @@ import {
23
23
  import {
24
24
  EXIT_CODES
25
25
  } from "./cli-46ycxe6r.js";
26
- import"./cli-4tx0szk7.js";
26
+ import"./cli-pfczdbyd.js";
27
27
  import"./cli-v5mp7a6q.js";
28
28
  import"./cli-37x76zdn.js";
29
29
 
@@ -2,21 +2,21 @@ import {
2
2
  executeValidation,
3
3
  publishTargetFor,
4
4
  reportMissingTools
5
- } from "./cli-02sh3r8x.js";
5
+ } from "./cli-c565qhpe.js";
6
6
  import {
7
7
  log
8
- } from "./cli-emp8wz36.js";
8
+ } from "./cli-43h754g9.js";
9
9
  import {
10
10
  UsageError,
11
11
  rejectExtraPositionals,
12
12
  rejectUnknownFlags
13
- } from "./cli-1bccnym3.js";
13
+ } from "./cli-kqg2xy7t.js";
14
14
  import"./cli-5vdgncmm.js";
15
15
  import"./cli-c41yr7he.js";
16
16
  import {
17
17
  EXIT_CODES
18
18
  } from "./cli-46ycxe6r.js";
19
- import"./cli-4tx0szk7.js";
19
+ import"./cli-pfczdbyd.js";
20
20
  import"./cli-v5mp7a6q.js";
21
21
  import"./cli-37x76zdn.js";
22
22
 
@@ -6,10 +6,10 @@ import {
6
6
  runBuild,
7
7
  splitOutPath,
8
8
  startPreviewServer
9
- } from "./cli-02sh3r8x.js";
9
+ } from "./cli-c565qhpe.js";
10
10
  import {
11
11
  log
12
- } from "./cli-emp8wz36.js";
12
+ } from "./cli-43h754g9.js";
13
13
  import {
14
14
  UsageError,
15
15
  parseFormat,
@@ -17,13 +17,13 @@ import {
17
17
  rejectExtraPositionals,
18
18
  rejectUnknownFlags,
19
19
  resolvePort
20
- } from "./cli-1bccnym3.js";
20
+ } from "./cli-kqg2xy7t.js";
21
21
  import"./cli-5vdgncmm.js";
22
22
  import"./cli-c41yr7he.js";
23
23
  import {
24
24
  BuildError
25
25
  } from "./cli-46ycxe6r.js";
26
- import"./cli-4tx0szk7.js";
26
+ import"./cli-pfczdbyd.js";
27
27
  import"./cli-v5mp7a6q.js";
28
28
  import"./cli-37x76zdn.js";
29
29
 
@@ -11,22 +11,22 @@ import {
11
11
  publishProviderFor,
12
12
  resolvePublishFormat,
13
13
  runPublish
14
- } from "./cli-02sh3r8x.js";
14
+ } from "./cli-c565qhpe.js";
15
15
  import {
16
16
  FileTokenStore,
17
17
  log
18
- } from "./cli-emp8wz36.js";
18
+ } from "./cli-43h754g9.js";
19
19
  import {
20
20
  UsageError,
21
21
  rejectExtraPositionals,
22
22
  rejectUnknownFlags
23
- } from "./cli-1bccnym3.js";
23
+ } from "./cli-kqg2xy7t.js";
24
24
  import"./cli-5vdgncmm.js";
25
25
  import"./cli-c41yr7he.js";
26
26
  import {
27
27
  EXIT_CODES
28
28
  } from "./cli-46ycxe6r.js";
29
- import"./cli-4tx0szk7.js";
29
+ import"./cli-pfczdbyd.js";
30
30
  import"./cli-v5mp7a6q.js";
31
31
  import"./cli-37x76zdn.js";
32
32
 
@@ -19,12 +19,14 @@ import {
19
19
  snapshotWorkingTreeUnlocked,
20
20
  stageChanges,
21
21
  switchBranch,
22
+ whenGitIdle,
22
23
  withRepoLock
23
- } from "./index-7mqst9tg.js";
24
+ } from "./index-fnhak0nh.js";
24
25
  import"./index-v5mp7a6q.js";
25
26
  import"./index-37x76zdn.js";
26
27
  export {
27
28
  withRepoLock,
29
+ whenGitIdle,
28
30
  switchBranch,
29
31
  stageChanges,
30
32
  snapshotWorkingTreeUnlocked,
@@ -19,12 +19,14 @@ import {
19
19
  snapshotWorkingTreeUnlocked,
20
20
  stageChanges,
21
21
  switchBranch,
22
+ whenGitIdle,
22
23
  withRepoLock
23
- } from "./cli-4tx0szk7.js";
24
+ } from "./cli-pfczdbyd.js";
24
25
  import"./cli-v5mp7a6q.js";
25
26
  import"./cli-37x76zdn.js";
26
27
  export {
27
28
  withRepoLock,
29
+ whenGitIdle,
28
30
  switchBranch,
29
31
  stageChanges,
30
32
  snapshotWorkingTreeUnlocked,
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-02sh3r8x.js";
3
+ } from "./cli-c565qhpe.js";
4
4
  import {
5
5
  log
6
- } from "./cli-emp8wz36.js";
6
+ } from "./cli-43h754g9.js";
7
7
  import {
8
8
  UsageError,
9
9
  rejectExtraPositionals,
10
10
  rejectUnknownFlags
11
- } from "./cli-1bccnym3.js";
11
+ } from "./cli-kqg2xy7t.js";
12
12
  import"./cli-5vdgncmm.js";
13
13
  import"./cli-c41yr7he.js";
14
14
  import {
15
15
  EXIT_CODES
16
16
  } from "./cli-46ycxe6r.js";
17
- import"./cli-4tx0szk7.js";
17
+ import"./cli-pfczdbyd.js";
18
18
  import"./cli-v5mp7a6q.js";
19
19
  import"./cli-37x76zdn.js";
20
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gutterpress",
3
- "version": "0.11.6",
3
+ "version": "0.11.7-alpha.2",
4
4
  "description": "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
5
5
  "author": "itlackey",
6
6
  "license": "MPL-2.0",