oh-my-space 2.0.0 → 2.0.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.
@@ -1 +1 @@
1
- {"commit":"b2a86e8876ac76ffc8e4daed8146f82fe93613d1","skills":{"oms-branch":{"version":"1.2.0","omsVersion":">=1.0.0-0"},"oms-pointer":{"version":"1.2.0","omsVersion":">=1.0.0-0"},"oms-workspace":{"version":"1.4.0","omsVersion":">=1.2.0-0"}}}
1
+ {"commit":"58af8b34c6d2801ea9900e8ff4275d3c2e70c1d6","skills":{"oms-branch":{"version":"1.2.0","omsVersion":">=1.0.0-0"},"oms-pointer":{"version":"1.2.0","omsVersion":">=1.0.0-0"},"oms-workspace":{"version":"1.4.0","omsVersion":">=1.2.0-0"}}}
package/dist/oms.js CHANGED
@@ -18591,6 +18591,7 @@ function makePlan(root, repo, baseArg) {
18591
18591
  const matches = refs.filter((entry) => requested.startsWith("refs/") ? entry.ref === requested : entry.ref === `refs/heads/${requested}` || entry.ref === `refs/remotes/${requested}`);
18592
18592
  if (matches.length !== 1 || matches[0].symbolic) throw new Error(`Comparison base ${JSON.stringify(requested)} is missing, ambiguous, or symbolic. Supply an existing direct local or remote-tracking branch with --base; no refs were refreshed.`);
18593
18593
  const base = matches[0];
18594
+ let limitedHistory = false;
18594
18595
  const branches = refs.filter((entry) => entry.ref.startsWith("refs/heads/")).map((entry) => {
18595
18596
  const name = entry.ref.slice("refs/heads/".length);
18596
18597
  const reasons = [...safety.protected.get(name) ?? []];
@@ -18598,11 +18599,14 @@ function makePlan(root, repo, baseArg) {
18598
18599
  if (entry.symbolic) reasons.push("symbolic local branch ref");
18599
18600
  if (!reasons.length) {
18600
18601
  const reason = ancestry(dir, entry.oid, base.oid, safety.shallow);
18601
- if (reason) reasons.push(reason);
18602
+ if (reason) {
18603
+ reasons.push(reason);
18604
+ if (safety.shallow) limitedHistory = true;
18605
+ }
18602
18606
  }
18603
18607
  return Object.freeze({ ...entry, name, reasons: Object.freeze(reasons) });
18604
18608
  }).sort((a2, b) => a2.name < b.name ? -1 : a2.name > b.name ? 1 : 0);
18605
- return Object.freeze({ alias: repo.alias, context, base, branches: Object.freeze(branches) });
18609
+ return Object.freeze({ alias: repo.alias, context, base, branches: Object.freeze(branches), limitedHistory });
18606
18610
  }
18607
18611
  __name(makePlan, "makePlan");
18608
18612
  function execute(root, repo, plan) {
@@ -18700,24 +18704,26 @@ async function runBranchClean(aliasArg, options) {
18700
18704
  const wasInitialized = submoduleInitialized(repoRoot, repo.alias);
18701
18705
  const preparation = await prepareAlias(repoRoot, repo, { command: "branch clean", topologyOffer: false });
18702
18706
  if (!preparation.ok) return preparation.code;
18703
- const effects = wasInitialized ? "Preparation: the source was already initialized; no initialization was needed." : "Preparation initialized the registered source; fetched data, baseline branch creation or attachment, and tracking configuration remain even if cleanup is declined.";
18707
+ const effects = wasInitialized ? void 0 : "Preparation initialized the registered source; fetched data, baseline branch creation or attachment, and tracking configuration remain even if cleanup is declined.";
18704
18708
  let plan;
18705
18709
  try {
18706
18710
  plan = makePlan(repoRoot, repo, options.base);
18707
18711
  } catch (error) {
18708
18712
  log.error(error instanceof Error ? error.message : String(error));
18709
- log.info(effects);
18713
+ if (effects) log.info(effects);
18710
18714
  return 1;
18711
18715
  }
18712
- log.info(`Cleanup ${plan.alias}: comparison base ${plan.base.ref} ${plan.base.oid} (local/cached refs; not refreshed).`);
18713
- log.info(effects);
18714
- log.warn("Do not mutate source branches, worktrees, or configuration through other Git or IDE operations from confirmation waiting through completion. Commit-value transactions do not atomically protect ref type, generation, occupancy, metadata, or configuration; same-name recreation and movement away and back to the same OID are not distinguished.");
18715
- for (const branch of plan.branches) log.info(`${branch.reasons.length ? "Excluded" : "Candidate"}: ${branch.name} ${branch.oid}${branch.reasons.length ? ` \u2014 ${branch.reasons.join(", ")}` : ""}`);
18716
18716
  const candidates = plan.branches.filter((branch) => !branch.reasons.length);
18717
18717
  if (!candidates.length) {
18718
- log.info("No eligible merged local branches to clean.");
18718
+ log.info(`${plan.alias}: no eligible merged local branches to clean.`);
18719
+ if (effects) log.info(effects);
18720
+ if (plan.limitedHistory) log.warn("Ancestry could not be proven with limited shallow history; deepen or repair history explicitly, then rerun.");
18719
18721
  return 0;
18720
18722
  }
18723
+ log.info(`Cleanup ${plan.alias}: comparison base ${plan.base.ref} ${plan.base.oid} (local/cached refs; not refreshed).`);
18724
+ if (effects) log.info(effects);
18725
+ log.warn("Do not mutate source branches, worktrees, or configuration through other Git or IDE operations from confirmation waiting through completion. Commit-value transactions do not atomically protect ref type, generation, occupancy, metadata, or configuration; same-name recreation and movement away and back to the same OID are not distinguished.");
18726
+ for (const branch of plan.branches) log.info(`${branch.reasons.length ? "Excluded" : "Candidate"}: ${branch.name} ${branch.oid}${branch.reasons.length ? ` \u2014 ${branch.reasons.join(", ")}` : ""}`);
18721
18727
  const rerun = `oms branch clean ${shq2(repo.alias)}${options.base !== void 0 ? ` --base ${shq2(options.base)}` : ""}`;
18722
18728
  if (!canPrompt()) {
18723
18729
  log.error(`No branches deleted. Rerun in an interactive terminal: ${rerun}`);
@@ -18726,7 +18732,7 @@ async function runBranchClean(aliasArg, options) {
18726
18732
  const confirmed = await guardedConfirm({ message: `Delete these ${candidates.length} merged local branches in ${repo.alias}?`, initialValue: false });
18727
18733
  if (isCancel2(confirmed) || !confirmed) {
18728
18734
  cancel("Cleanup declined or cancelled; no branches deleted.");
18729
- log.info(effects);
18735
+ if (effects) log.info(effects);
18730
18736
  return 1;
18731
18737
  }
18732
18738
  const outcomes = execute(repoRoot, repo, plan);
@@ -20223,36 +20229,16 @@ fresh clone has no deletable local branch. Partial registration is refused with
20223
20229
  Deletion remains local to the submodule and never changes root topology.
20224
20230
  `;
20225
20231
  var branchCleanHelp = `
20226
- Clean merged local branches in one source repository. Omit the alias for interactive selection.
20227
- OMS does not accept --all, --force, or --yes.
20228
-
20229
- Base:
20230
- The default is the local oms.yaml branch, or the local branch named by cached origin/HEAD.
20231
- OMS has no default named main and no remote fallback.
20232
- --base selects an existing direct local or remote-tracking branch. Protected baselines still apply.
20233
- OMS does not refresh refs or reconcile remotes after preparation.
20234
-
20235
- Safety:
20236
- - OMS displays the base, branch tips, exclusions, and preparation effects before one confirmation.
20237
- - Confirmation defaults to No. Candidates require an interactive terminal.
20238
- - Only proven ancestry qualifies, including in shallow repositories.
20239
- - OMS excludes the current branch, local base, protected baselines, and branches in any worktree.
20240
- - OMS refuses unsafe source state, inconsistent registration, and unreliable inspection.
20241
- - Initialization, fetched data, baseline attachment or creation, and tracking settings remain after decline.
20242
- - Stop other Git or IDE changes to source branches, worktrees, and configuration from confirmation waiting until cleanup finishes.
20243
- - Commit checks do not lock all repository state. Concurrent recreation can lose branch settings.
20244
-
20245
- Results:
20246
- OMS prints recovery commands. Completed deletions remain after partial failure, including configuration failure.
20247
- OMS does not retry with force or restore deleted branches automatically.
20248
- After preparation, OMS preserves remote refs, source HEAD/files/index, root tracked state, and recorded commits.
20249
- Exit codes: 0 complete or empty batch | 1 refusal/decline/cancel | 2 initialization failure or incomplete batch
20250
-
20251
20232
  Examples:
20252
20233
  $ oms branch clean api
20253
20234
  $ oms branch clean api --base origin/develop
20254
20235
 
20255
- Full rules for refs, source state, revalidation, concurrency, shallow history, and recovery:
20236
+ Deletes local branches only, with interactive confirmation that defaults to No.
20237
+ The default base is the configured local branch, or the local branch named by
20238
+ cached origin/HEAD. Refs are not refreshed after preparation.
20239
+ OMS initializes existing registrations when needed; those effects remain on decline.
20240
+
20241
+ Detailed safety and recovery:
20256
20242
  https://github.com/divlook/oh-my-space/blob/HEAD/docs/how-oms-works.md#merged-branch-cleanup-safety
20257
20243
  `;
20258
20244
  var treeHelp = `
@@ -20752,7 +20738,7 @@ branchCommand.command("delete").description(
20752
20738
  ).argument("[alias]", "declared source alias (omit to pick interactively)").argument("[branch]", "local branch name (omit to pick from deletable local branches)").option("-f, --force", "force-delete with git branch -D (still respects protected branches)").addHelpText("after", `${branchDeleteHelp}${workspaceContextHelp}${exitHelp}`).action(async (alias, branch, options) => {
20753
20739
  await exitWith(runBranchDelete(alias, branch, options));
20754
20740
  });
20755
- branchCommand.command("clean").description("Confirm deletion of merged local branches in one source repository.").argument("[alias]", "declared source alias (omit to pick interactively)").option("--base <ref>", "existing local or remote-tracking comparison branch").addHelpText("after", `${branchCleanHelp}${workspaceContextHelp}`).action(async (alias, options) => {
20741
+ branchCommand.command("clean").description("Confirm deletion of merged local branches in one source repository.").argument("[alias]", "declared source alias (omit to pick interactively)").option("--base <ref>", "existing local or remote-tracking comparison branch").addHelpText("after", branchCleanHelp).action(async (alias, options) => {
20756
20742
  await exitWith(runBranchClean(alias, options));
20757
20743
  });
20758
20744
  var treeCommand = program2.command("tree").description("Create, list, or remove a disposable per-task checkout of a source repository.").addHelpText("after", `${treeHelp}${workspaceContextHelp}${exitHelp}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-space",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Manage multi-repo workspaces with Git submodules.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/divlook/oh-my-space",