tonal-guitar 0.3.0 → 0.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 CHANGED
@@ -137,7 +137,7 @@ fretboard(STANDARD, [0, 4]); // every note on strings 0-5, frets 0-4
137
137
 
138
138
  ### Shape Registry
139
139
 
140
- Built-in shapes are registered at import time: CAGED scale shapes (5), CAGED chord shapes (5), 3NPS patterns (7), pentatonic boxes (5) -- plus (v0.2.0) 5 minor CAGED scale shapes and 5 minor pentatonic boxes, derived from the major-frame shapes via `relabelShape`. See [Minor-Quality Entries](#minor-quality-entries) below.
140
+ Built-in shapes are registered at import time: CAGED scale shapes (5), CAGED chord shapes (5), 3NPS patterns (7), pentatonic boxes (5) -- plus (v0.2.0) 5 minor CAGED scale shapes and 5 minor pentatonic boxes, derived from the major-frame shapes via `relabelShape`, and 5 minor + 5 major blues boxes, derived via `addPassingTone`. See [Minor-Quality Entries](#minor-quality-entries) and [Blues Boxes](#blues-boxes) below.
141
141
 
142
142
  #### `get(name: string) => ScaleShape | undefined`
143
143
 
@@ -292,6 +292,40 @@ buildFrettedScale(get("G Shape"), "C").notes;
292
292
  buildFrettedScale(get("Em Shape"), "A").notes; // same {string, fret} pairs, A=1P, C=3m
293
293
  ```
294
294
 
295
+ ### Blues Boxes
296
+
297
+ #### `addPassingTone(shape: ScaleShape, tone: string, options?: PassingToneOptions) => ScaleShape | undefined`
298
+
299
+ Adds a chromatic passing tone to any scale shape -- e.g. the b5 (`"5d"`) that turns a minor pentatonic box into a minor blues box, the b3 (`"3m"`) that turns a major pentatonic box into a major blues box, or a `"7M"` on a mixolydian shape for bebop dominant.
300
+
301
+ Placement rule: the tone goes on the same string, one fret above every note a semitone below it (the b5 sits right above each 4P). Tones inside the shape's existing pitch range are always kept, even if they need a one-fret stretch; a tone that would become the shape's new highest note is kept only if it fits within the existing fret span. Fret geometry is evaluated in `options.tuning` (default `STANDARD`). Returns `undefined` for an invalid tone, a shape that doesn't build, or when nothing can be placed (no semitone-below neighbor, or the pitch is already present).
302
+
303
+ ```js
304
+ import { addPassingTone, get } from "tonal-guitar";
305
+
306
+ const blues = addPassingTone(get("Em Shape"), "5d", { name: "Em Blues", quality: "minor-blues" });
307
+
308
+ interface PassingToneOptions {
309
+ name?: string; // override the result name (default: shape.name)
310
+ quality?: string; // value written to result.quality
311
+ parentShape?: string; // value written to result.parentShape (default: shape.name)
312
+ tuning?: string[]; // tuning for the stretch rule (default: STANDARD)
313
+ }
314
+ ```
315
+
316
+ Registered blues boxes (all `system: "pentatonic"`, box numbers shared with the pentatonic boxes):
317
+
318
+ | Registered name | Derived from | `quality` | b5 frets in A minor blues |
319
+ | --- | --- | --- | --- |
320
+ | `"Blues Box 1 Minor"` | `"Pentatonic Box 1 Minor"` + `5d` | `"minor-blues"` | A:6, G:8 |
321
+ | `"Blues Box 2 Minor"` | `"Pentatonic Box 2 Minor"` + `5d` | `"minor-blues"` | low E:11, G:8 |
322
+ | `"Blues Box 3 Minor"` | `"Pentatonic Box 3 Minor"` + `5d` | `"minor-blues"` | low E:11, D:13, high E:11 |
323
+ | `"Blues Box 4 Minor"` | `"Pentatonic Box 4 Minor"` + `5d` | `"minor-blues"` | D:13, B:16 |
324
+ | `"Blues Box 5 Minor"` | `"Pentatonic Box 5 Minor"` + `5d` | `"minor-blues"` | A:6, B:4 |
325
+ | `"Blues Box N Major"` | `"Blues Box N Minor"` relabeled | `"major-blues"` | same frets (C major blues = A minor blues) |
326
+
327
+ They work with Tonal's scale names: `buildFromScale(get("Blues Box 1 Minor"), "E blues")` (`"blues"` is Tonal's alias for `"minor blues"`), `modeShapes("A blues")`, `isShapeCompatible(shape, "C major blues")`, and `relatedScales` (minor blues ↔ relative major blues).
328
+
295
329
  ### Pattern Generators
296
330
 
297
331
  All generators return `number[]` degree sequences.
package/dist/index.d.mts CHANGED
@@ -80,9 +80,8 @@ interface Barre {
80
80
  * IS a `ScaleShape` (it only narrows `chordType` to required and adds a few
81
81
  * arpeggio-specific fields), so `buildFrettedScale`, `walkShape`,
82
82
  * `inferShapeContext` and `checkScaleBuildLoss` all work unchanged on it
83
- * with no code changes in this feature. No seed data ships for this
84
- * interface yet — see the `arpeggioShapes` registry (later group) for where
85
- * it starts getting populated.
83
+ * with no code changes in this feature. Built-in seeds live in
84
+ * `data/caged-arpeggios.ts` (registered into `arpeggioShapes`).
86
85
  */
87
86
  interface ArpeggioShape extends ScaleShape {
88
87
  chordType: string;
@@ -131,9 +130,13 @@ declare function playedStringSet(shape: ChordShape): number[];
131
130
  */
132
131
  declare function impliedStringSet(shape: ChordShape): number[];
133
132
  /**
134
- * The grip base fret for a set of per-string frets: the minimum *fretted*
135
- * (non-null, non-zero) fret, or `0` when there are no fretted strings (all
136
- * open/muted). Open strings (`0`) never set the grip base — see D-010.
133
+ * The grip base fret for a set of per-string frets: the minimum *played*
134
+ * (non-null) fret, open strings (`0`) included, or `0` when every string is
135
+ * muted. Including open strings is what makes the base root-invariant
136
+ * (D-010 as amended by CR-002 / #192): a shape whose root string lands on
137
+ * the nut at one root (E Shape at E, A Form at A, ...) keeps the same
138
+ * base-relative geometry as at every other root, so a `Barre.fret` offset
139
+ * resolves correctly everywhere.
137
140
  */
138
141
  declare function gripBaseFret(frets: (number | null)[]): number;
139
142
  /**
@@ -446,7 +449,7 @@ declare function autoFingering(shape: Omit<ChordShape, "fingers" | "barres">, ro
446
449
  barres: Barre[];
447
450
  };
448
451
 
449
- declare const VERSION = "0.3.0";
452
+ declare const VERSION = "0.4.0";
450
453
 
451
454
  /**
452
455
  * Shape visual/quality audit checks.
@@ -641,9 +644,9 @@ declare function checkTuningMismatch(shape: ChordShape, tuning?: string[]): Shap
641
644
  * Flags a `Barre.fret` that cannot be a valid grip-base offset (D-010):
642
645
  *
643
646
  * 1. `fret < 0` — an offset is never negative.
644
- * 2. `fret > span` — `span` is the shape's own fretted span (same
645
- * `checkFretSpan` computation: max − min over non-null, non-open built
646
- * frets), and an offset can never exceed the span it's measured within.
647
+ * 2. `fret > span` — `span` is the range the offset is measured within:
648
+ * the highest played built fret minus the grip base (`gripBaseFret`,
649
+ * open strings included), so an offset can never exceed it.
647
650
  * 3. For `baseFret`-carrying shapes with a resolvable grip root (see
648
651
  * `chordShapeGeometry`): `fret` equals the ABSOLUTE fret the source
649
652
  * diagram implies for the barre's strings (`sourceFrets[barre.fromString]`)
@@ -656,6 +659,14 @@ declare function checkTuningMismatch(shape: ChordShape, tuning?: string[]): Shap
656
659
  * `extended-chords.ts`, `caged-chords*.ts`) have since had their own
657
660
  * pre-D-010 absolute barre frets migrated to grip-base offsets too
658
661
  * (CR-001).
662
+ * 4. The offset resolves (`absoluteBarreFret(barre, gripBase)`) to a fret
663
+ * that doesn't match the grip: a string under the barre carrying the
664
+ * barre's finger sits at a different fret, or a played string under the
665
+ * barre sits below it. This is the root-invariance gate (CR-002 / #192):
666
+ * because built grips transpose rigidly and the grip base includes open
667
+ * strings, an offset that passes here at one root passes at every root —
668
+ * so it also catches offsets still measured from the old open-string-
669
+ * excluding base.
659
670
  *
660
671
  * `root`/`tuning`/`prebuilt` mirror `checkFretSpan`'s signature so
661
672
  * `auditChordShape` can thread its single hoisted `applyChordShape` build in
@@ -1289,10 +1300,13 @@ declare function scoreShapeMatch(probe: InferenceProbe, _shape: ScaleShape, root
1289
1300
  /**
1290
1301
  * Shape relabeling: rewrite a ScaleShape's per-string interval labels into
1291
1302
  * a different (rotation-compatible) interval frame, e.g. turning a
1292
- * major-frame CAGED shape into its natural-minor labeling.
1303
+ * major-frame CAGED shape into its natural-minor labeling — and
1304
+ * passing-tone augmentation (`addPassingTone`), e.g. adding the b5 that
1305
+ * turns a minor pentatonic box into a blues box.
1293
1306
  *
1294
- * Pure tier — MAY import `@tonaljs/interval` (required peer, already used
1295
- * by build.ts) and `./shape` (types only). MUST NOT import
1307
+ * Required-peer tier — MAY import `@tonaljs/interval`, `./build` (for
1308
+ * `addPassingTone`'s fret geometry), `./tuning`, and `./shape` (types
1309
+ * only). MUST NOT import
1296
1310
  * `@tonaljs/scale`/`@tonaljs/chord`/`@tonaljs/key` or `./integration`, so
1297
1311
  * `src/data/*` can call this at import time with zero optional peers.
1298
1312
  */
@@ -1314,6 +1328,31 @@ interface RelabelOptions {
1314
1328
  * convention, cf. `src/build.ts:188,192`) when no valid relabeling exists.
1315
1329
  */
1316
1330
  declare function relabelShape(shape: ScaleShape, targetIntervals: string[], options?: RelabelOptions): ScaleShape | undefined;
1331
+ interface PassingToneOptions extends RelabelOptions {
1332
+ tuning?: string[];
1333
+ }
1334
+ /**
1335
+ * Add a chromatic passing tone to a shape, e.g. the b5 (`"5d"`) that turns
1336
+ * a minor pentatonic box into a minor blues box, or the b3 (`"3m"`) that
1337
+ * turns a major pentatonic box into a major blues box.
1338
+ *
1339
+ * Placement rule: `tone` is inserted on the same string, one fret above
1340
+ * every note whose chroma is a semitone below `tone` (the b5 sits right
1341
+ * above each 4P). Every inserted tone that lands inside the shape's
1342
+ * existing pitch range is kept, even when it needs a one-fret stretch past
1343
+ * the shape's fret span. A tone that would become the shape's new highest
1344
+ * note is kept only when it fits inside the existing fret span — edge
1345
+ * tones are never added at the cost of a stretch.
1346
+ *
1347
+ * Fret geometry comes from building the shape (at root C) in
1348
+ * `options.tuning`. Interval labels, `rootString`, and `span` are otherwise
1349
+ * unchanged; `name`/`quality`/`parentShape` follow `relabelShape`'s option
1350
+ * semantics (`parentShape` defaults to the input shape's name).
1351
+ *
1352
+ * Returns `undefined` for an invalid `tone`, a shape that does not build,
1353
+ * or when no passing tone can be placed.
1354
+ */
1355
+ declare function addPassingTone(shape: ScaleShape, tone: string, options?: PassingToneOptions): ScaleShape | undefined;
1317
1356
 
1318
1357
  /**
1319
1358
  * Tonal integration: connects guitar shapes to Scale, Chord, Mode, Key, and Pcset.
@@ -1818,4 +1857,4 @@ declare const SEQ_UP_DOWN: number[];
1818
1857
  declare const SEQ_TRIAD_CLIMB: number[];
1819
1858
  declare const SEQ_1357_DESC: number[];
1820
1859
 
1821
- export { ASCENDING_THIRDS, type AddChange, type AlphaTexOptions, type ArpeggioResolution, type ArpeggioShape, type ArpeggioSlot, type ArpeggioTier, type AsciiTabOptions, type AuditSeverity, type Barre, CHECK_BARRE_FRET_ORIGIN, CHECK_BUILD_LOSS, CHECK_CHORD_TONES_ONLY, CHECK_CONTAINS_CHORD_GRIP, CHECK_COVERS_CHORD, CHECK_FINGERING_COMPLETE, CHECK_FINGER_ZERO_ON_MOVABLE, CHECK_FRET_SPAN, CHECK_GEOMETRY_MISMATCH, CHECK_IDENTIFY_MISMATCH, CHECK_METADATA_COMPLETENESS, CHECK_NAME_UNIQUE, CHECK_OVERRIDES_TARGET, CHECK_POSITION_SPAN, CHECK_REPEATED_FINGER_NO_BARRE, CHECK_STRINGSET_MISMATCH, CHECK_TUNING_MISMATCH, CHORD_SCALE_RULE, CHORD_SCALE_RULE_VERSION, type CagedPosition, type ChainDirection, type Changeset, type ChangesetChange, type ChangesetKind, type ChordGeometryDetails, type ChordScaleEntry, type ChordShape, type ChordShapeAuditResult, type ConnectSequencesInput, type ConnectSequencesResult, type ConnectorOptions, type ConnectorStrategy, type ContainingScale, DADGAD, DEFAULT_SCALE_CORPUS, DESCENDING_THIRDS, DROP_D, type Fingering, type FretboardPosition, type FrettedNote, type FrettedScale, type InferenceCandidate, type InferenceInput, type InferenceOptions, type InferenceProbe, type KeyAnalysis, NoFrettedScale, OPEN_G, type RelabelOptions, type RemoveChange, SEQ_1234_GROUP, SEQ_1235, SEQ_1357_DESC, SEQ_TRIAD_CLIMB, SEQ_UP_DOWN, SHELL_DICTIONARY, STANDARD, STANDARD_7, STANDARD_8, type ScaleShape, type ScalesContainingChordOptions, type ScalesContainingChordResult, type ScoreBreakdown, type SequenceOptions, type ShapeAuditIssue, type ShapeAuditOptions, type UpdateChange, VERSION, type VoicingFamily, type VoicingPatternDictionary, type WalkOptions, type WalkShapeOptions, absoluteBarreFret, add, all, analyzeInKey, applyChordShape, applySequence, arpeggioFor, arpeggioFromScale, arpeggioFromShape, arpeggioShapes, arpeggioSlotKey, ascendingIntervals, ascendingLinear, auditAllShapes, auditAllShapesIntegration, auditArpeggioShape, auditArpeggioShapeIntegration, auditChordShape, auditChordShapeFull, auditChordShapeIntegration, auditScaleShape, autoFingering, buildFrettedScale, buildFromScale, checkBarreFretOrigin, checkChordBuildLoss, checkChordMetadataCompleteness, checkChordTonesOnly, checkContainsChordGrip, checkCoversChord, checkFingerZeroOnMovable, checkFingeringComplete, checkFretSpan, checkGeometryMismatch, checkIdentifyMismatch, checkNameUnique, checkOverridesTarget, checkPositionSpan, checkRepeatedFingerNoBarre, checkScaleBuildLoss, checkScaleMetadataCompleteness, checkStringsetMismatch, checkTuningMismatch, chordShapeGeometry, chordShapes, connectSequences, descendingIntervals, descendingLinear, displayRootFor, exportIdentifierFor, filterChordTones, findFretInPosition, findNearestFret, findNote, flattenSequence, formatChordFrets, fourths, fretFor, fretboard, get, gripBaseFret, grouping, identifyChord, impliedStringSet, inferShapeContext, isMovable, isShapeCompatible, modeShapes, names, noteAt, parentBoxForChordShape, parseChordFrets, parseScalePattern, playedStringSet, relabelShape, relabelShapeToScale, relatedScales, remove, removeAll, resolveArpeggioForSlot, scaleTypeForChordType, scalesContainingChord, scoreShapeMatch, sixths, slotForChordShape, sourceGripBaseFret, thirds, toAlphaTeX, toAsciiTab, visibleArpeggios, walkPattern, walkShape, walkShapeIntervals, walkShapeMotif };
1860
+ export { ASCENDING_THIRDS, type AddChange, type AlphaTexOptions, type ArpeggioResolution, type ArpeggioShape, type ArpeggioSlot, type ArpeggioTier, type AsciiTabOptions, type AuditSeverity, type Barre, CHECK_BARRE_FRET_ORIGIN, CHECK_BUILD_LOSS, CHECK_CHORD_TONES_ONLY, CHECK_CONTAINS_CHORD_GRIP, CHECK_COVERS_CHORD, CHECK_FINGERING_COMPLETE, CHECK_FINGER_ZERO_ON_MOVABLE, CHECK_FRET_SPAN, CHECK_GEOMETRY_MISMATCH, CHECK_IDENTIFY_MISMATCH, CHECK_METADATA_COMPLETENESS, CHECK_NAME_UNIQUE, CHECK_OVERRIDES_TARGET, CHECK_POSITION_SPAN, CHECK_REPEATED_FINGER_NO_BARRE, CHECK_STRINGSET_MISMATCH, CHECK_TUNING_MISMATCH, CHORD_SCALE_RULE, CHORD_SCALE_RULE_VERSION, type CagedPosition, type ChainDirection, type Changeset, type ChangesetChange, type ChangesetKind, type ChordGeometryDetails, type ChordScaleEntry, type ChordShape, type ChordShapeAuditResult, type ConnectSequencesInput, type ConnectSequencesResult, type ConnectorOptions, type ConnectorStrategy, type ContainingScale, DADGAD, DEFAULT_SCALE_CORPUS, DESCENDING_THIRDS, DROP_D, type Fingering, type FretboardPosition, type FrettedNote, type FrettedScale, type InferenceCandidate, type InferenceInput, type InferenceOptions, type InferenceProbe, type KeyAnalysis, NoFrettedScale, OPEN_G, type PassingToneOptions, type RelabelOptions, type RemoveChange, SEQ_1234_GROUP, SEQ_1235, SEQ_1357_DESC, SEQ_TRIAD_CLIMB, SEQ_UP_DOWN, SHELL_DICTIONARY, STANDARD, STANDARD_7, STANDARD_8, type ScaleShape, type ScalesContainingChordOptions, type ScalesContainingChordResult, type ScoreBreakdown, type SequenceOptions, type ShapeAuditIssue, type ShapeAuditOptions, type UpdateChange, VERSION, type VoicingFamily, type VoicingPatternDictionary, type WalkOptions, type WalkShapeOptions, absoluteBarreFret, add, addPassingTone, all, analyzeInKey, applyChordShape, applySequence, arpeggioFor, arpeggioFromScale, arpeggioFromShape, arpeggioShapes, arpeggioSlotKey, ascendingIntervals, ascendingLinear, auditAllShapes, auditAllShapesIntegration, auditArpeggioShape, auditArpeggioShapeIntegration, auditChordShape, auditChordShapeFull, auditChordShapeIntegration, auditScaleShape, autoFingering, buildFrettedScale, buildFromScale, checkBarreFretOrigin, checkChordBuildLoss, checkChordMetadataCompleteness, checkChordTonesOnly, checkContainsChordGrip, checkCoversChord, checkFingerZeroOnMovable, checkFingeringComplete, checkFretSpan, checkGeometryMismatch, checkIdentifyMismatch, checkNameUnique, checkOverridesTarget, checkPositionSpan, checkRepeatedFingerNoBarre, checkScaleBuildLoss, checkScaleMetadataCompleteness, checkStringsetMismatch, checkTuningMismatch, chordShapeGeometry, chordShapes, connectSequences, descendingIntervals, descendingLinear, displayRootFor, exportIdentifierFor, filterChordTones, findFretInPosition, findNearestFret, findNote, flattenSequence, formatChordFrets, fourths, fretFor, fretboard, get, gripBaseFret, grouping, identifyChord, impliedStringSet, inferShapeContext, isMovable, isShapeCompatible, modeShapes, names, noteAt, parentBoxForChordShape, parseChordFrets, parseScalePattern, playedStringSet, relabelShape, relabelShapeToScale, relatedScales, remove, removeAll, resolveArpeggioForSlot, scaleTypeForChordType, scalesContainingChord, scoreShapeMatch, sixths, slotForChordShape, sourceGripBaseFret, thirds, toAlphaTeX, toAsciiTab, visibleArpeggios, walkPattern, walkShape, walkShapeIntervals, walkShapeMotif };
package/dist/index.d.ts CHANGED
@@ -80,9 +80,8 @@ interface Barre {
80
80
  * IS a `ScaleShape` (it only narrows `chordType` to required and adds a few
81
81
  * arpeggio-specific fields), so `buildFrettedScale`, `walkShape`,
82
82
  * `inferShapeContext` and `checkScaleBuildLoss` all work unchanged on it
83
- * with no code changes in this feature. No seed data ships for this
84
- * interface yet — see the `arpeggioShapes` registry (later group) for where
85
- * it starts getting populated.
83
+ * with no code changes in this feature. Built-in seeds live in
84
+ * `data/caged-arpeggios.ts` (registered into `arpeggioShapes`).
86
85
  */
87
86
  interface ArpeggioShape extends ScaleShape {
88
87
  chordType: string;
@@ -131,9 +130,13 @@ declare function playedStringSet(shape: ChordShape): number[];
131
130
  */
132
131
  declare function impliedStringSet(shape: ChordShape): number[];
133
132
  /**
134
- * The grip base fret for a set of per-string frets: the minimum *fretted*
135
- * (non-null, non-zero) fret, or `0` when there are no fretted strings (all
136
- * open/muted). Open strings (`0`) never set the grip base — see D-010.
133
+ * The grip base fret for a set of per-string frets: the minimum *played*
134
+ * (non-null) fret, open strings (`0`) included, or `0` when every string is
135
+ * muted. Including open strings is what makes the base root-invariant
136
+ * (D-010 as amended by CR-002 / #192): a shape whose root string lands on
137
+ * the nut at one root (E Shape at E, A Form at A, ...) keeps the same
138
+ * base-relative geometry as at every other root, so a `Barre.fret` offset
139
+ * resolves correctly everywhere.
137
140
  */
138
141
  declare function gripBaseFret(frets: (number | null)[]): number;
139
142
  /**
@@ -446,7 +449,7 @@ declare function autoFingering(shape: Omit<ChordShape, "fingers" | "barres">, ro
446
449
  barres: Barre[];
447
450
  };
448
451
 
449
- declare const VERSION = "0.3.0";
452
+ declare const VERSION = "0.4.0";
450
453
 
451
454
  /**
452
455
  * Shape visual/quality audit checks.
@@ -641,9 +644,9 @@ declare function checkTuningMismatch(shape: ChordShape, tuning?: string[]): Shap
641
644
  * Flags a `Barre.fret` that cannot be a valid grip-base offset (D-010):
642
645
  *
643
646
  * 1. `fret < 0` — an offset is never negative.
644
- * 2. `fret > span` — `span` is the shape's own fretted span (same
645
- * `checkFretSpan` computation: max − min over non-null, non-open built
646
- * frets), and an offset can never exceed the span it's measured within.
647
+ * 2. `fret > span` — `span` is the range the offset is measured within:
648
+ * the highest played built fret minus the grip base (`gripBaseFret`,
649
+ * open strings included), so an offset can never exceed it.
647
650
  * 3. For `baseFret`-carrying shapes with a resolvable grip root (see
648
651
  * `chordShapeGeometry`): `fret` equals the ABSOLUTE fret the source
649
652
  * diagram implies for the barre's strings (`sourceFrets[barre.fromString]`)
@@ -656,6 +659,14 @@ declare function checkTuningMismatch(shape: ChordShape, tuning?: string[]): Shap
656
659
  * `extended-chords.ts`, `caged-chords*.ts`) have since had their own
657
660
  * pre-D-010 absolute barre frets migrated to grip-base offsets too
658
661
  * (CR-001).
662
+ * 4. The offset resolves (`absoluteBarreFret(barre, gripBase)`) to a fret
663
+ * that doesn't match the grip: a string under the barre carrying the
664
+ * barre's finger sits at a different fret, or a played string under the
665
+ * barre sits below it. This is the root-invariance gate (CR-002 / #192):
666
+ * because built grips transpose rigidly and the grip base includes open
667
+ * strings, an offset that passes here at one root passes at every root —
668
+ * so it also catches offsets still measured from the old open-string-
669
+ * excluding base.
659
670
  *
660
671
  * `root`/`tuning`/`prebuilt` mirror `checkFretSpan`'s signature so
661
672
  * `auditChordShape` can thread its single hoisted `applyChordShape` build in
@@ -1289,10 +1300,13 @@ declare function scoreShapeMatch(probe: InferenceProbe, _shape: ScaleShape, root
1289
1300
  /**
1290
1301
  * Shape relabeling: rewrite a ScaleShape's per-string interval labels into
1291
1302
  * a different (rotation-compatible) interval frame, e.g. turning a
1292
- * major-frame CAGED shape into its natural-minor labeling.
1303
+ * major-frame CAGED shape into its natural-minor labeling — and
1304
+ * passing-tone augmentation (`addPassingTone`), e.g. adding the b5 that
1305
+ * turns a minor pentatonic box into a blues box.
1293
1306
  *
1294
- * Pure tier — MAY import `@tonaljs/interval` (required peer, already used
1295
- * by build.ts) and `./shape` (types only). MUST NOT import
1307
+ * Required-peer tier — MAY import `@tonaljs/interval`, `./build` (for
1308
+ * `addPassingTone`'s fret geometry), `./tuning`, and `./shape` (types
1309
+ * only). MUST NOT import
1296
1310
  * `@tonaljs/scale`/`@tonaljs/chord`/`@tonaljs/key` or `./integration`, so
1297
1311
  * `src/data/*` can call this at import time with zero optional peers.
1298
1312
  */
@@ -1314,6 +1328,31 @@ interface RelabelOptions {
1314
1328
  * convention, cf. `src/build.ts:188,192`) when no valid relabeling exists.
1315
1329
  */
1316
1330
  declare function relabelShape(shape: ScaleShape, targetIntervals: string[], options?: RelabelOptions): ScaleShape | undefined;
1331
+ interface PassingToneOptions extends RelabelOptions {
1332
+ tuning?: string[];
1333
+ }
1334
+ /**
1335
+ * Add a chromatic passing tone to a shape, e.g. the b5 (`"5d"`) that turns
1336
+ * a minor pentatonic box into a minor blues box, or the b3 (`"3m"`) that
1337
+ * turns a major pentatonic box into a major blues box.
1338
+ *
1339
+ * Placement rule: `tone` is inserted on the same string, one fret above
1340
+ * every note whose chroma is a semitone below `tone` (the b5 sits right
1341
+ * above each 4P). Every inserted tone that lands inside the shape's
1342
+ * existing pitch range is kept, even when it needs a one-fret stretch past
1343
+ * the shape's fret span. A tone that would become the shape's new highest
1344
+ * note is kept only when it fits inside the existing fret span — edge
1345
+ * tones are never added at the cost of a stretch.
1346
+ *
1347
+ * Fret geometry comes from building the shape (at root C) in
1348
+ * `options.tuning`. Interval labels, `rootString`, and `span` are otherwise
1349
+ * unchanged; `name`/`quality`/`parentShape` follow `relabelShape`'s option
1350
+ * semantics (`parentShape` defaults to the input shape's name).
1351
+ *
1352
+ * Returns `undefined` for an invalid `tone`, a shape that does not build,
1353
+ * or when no passing tone can be placed.
1354
+ */
1355
+ declare function addPassingTone(shape: ScaleShape, tone: string, options?: PassingToneOptions): ScaleShape | undefined;
1317
1356
 
1318
1357
  /**
1319
1358
  * Tonal integration: connects guitar shapes to Scale, Chord, Mode, Key, and Pcset.
@@ -1818,4 +1857,4 @@ declare const SEQ_UP_DOWN: number[];
1818
1857
  declare const SEQ_TRIAD_CLIMB: number[];
1819
1858
  declare const SEQ_1357_DESC: number[];
1820
1859
 
1821
- export { ASCENDING_THIRDS, type AddChange, type AlphaTexOptions, type ArpeggioResolution, type ArpeggioShape, type ArpeggioSlot, type ArpeggioTier, type AsciiTabOptions, type AuditSeverity, type Barre, CHECK_BARRE_FRET_ORIGIN, CHECK_BUILD_LOSS, CHECK_CHORD_TONES_ONLY, CHECK_CONTAINS_CHORD_GRIP, CHECK_COVERS_CHORD, CHECK_FINGERING_COMPLETE, CHECK_FINGER_ZERO_ON_MOVABLE, CHECK_FRET_SPAN, CHECK_GEOMETRY_MISMATCH, CHECK_IDENTIFY_MISMATCH, CHECK_METADATA_COMPLETENESS, CHECK_NAME_UNIQUE, CHECK_OVERRIDES_TARGET, CHECK_POSITION_SPAN, CHECK_REPEATED_FINGER_NO_BARRE, CHECK_STRINGSET_MISMATCH, CHECK_TUNING_MISMATCH, CHORD_SCALE_RULE, CHORD_SCALE_RULE_VERSION, type CagedPosition, type ChainDirection, type Changeset, type ChangesetChange, type ChangesetKind, type ChordGeometryDetails, type ChordScaleEntry, type ChordShape, type ChordShapeAuditResult, type ConnectSequencesInput, type ConnectSequencesResult, type ConnectorOptions, type ConnectorStrategy, type ContainingScale, DADGAD, DEFAULT_SCALE_CORPUS, DESCENDING_THIRDS, DROP_D, type Fingering, type FretboardPosition, type FrettedNote, type FrettedScale, type InferenceCandidate, type InferenceInput, type InferenceOptions, type InferenceProbe, type KeyAnalysis, NoFrettedScale, OPEN_G, type RelabelOptions, type RemoveChange, SEQ_1234_GROUP, SEQ_1235, SEQ_1357_DESC, SEQ_TRIAD_CLIMB, SEQ_UP_DOWN, SHELL_DICTIONARY, STANDARD, STANDARD_7, STANDARD_8, type ScaleShape, type ScalesContainingChordOptions, type ScalesContainingChordResult, type ScoreBreakdown, type SequenceOptions, type ShapeAuditIssue, type ShapeAuditOptions, type UpdateChange, VERSION, type VoicingFamily, type VoicingPatternDictionary, type WalkOptions, type WalkShapeOptions, absoluteBarreFret, add, all, analyzeInKey, applyChordShape, applySequence, arpeggioFor, arpeggioFromScale, arpeggioFromShape, arpeggioShapes, arpeggioSlotKey, ascendingIntervals, ascendingLinear, auditAllShapes, auditAllShapesIntegration, auditArpeggioShape, auditArpeggioShapeIntegration, auditChordShape, auditChordShapeFull, auditChordShapeIntegration, auditScaleShape, autoFingering, buildFrettedScale, buildFromScale, checkBarreFretOrigin, checkChordBuildLoss, checkChordMetadataCompleteness, checkChordTonesOnly, checkContainsChordGrip, checkCoversChord, checkFingerZeroOnMovable, checkFingeringComplete, checkFretSpan, checkGeometryMismatch, checkIdentifyMismatch, checkNameUnique, checkOverridesTarget, checkPositionSpan, checkRepeatedFingerNoBarre, checkScaleBuildLoss, checkScaleMetadataCompleteness, checkStringsetMismatch, checkTuningMismatch, chordShapeGeometry, chordShapes, connectSequences, descendingIntervals, descendingLinear, displayRootFor, exportIdentifierFor, filterChordTones, findFretInPosition, findNearestFret, findNote, flattenSequence, formatChordFrets, fourths, fretFor, fretboard, get, gripBaseFret, grouping, identifyChord, impliedStringSet, inferShapeContext, isMovable, isShapeCompatible, modeShapes, names, noteAt, parentBoxForChordShape, parseChordFrets, parseScalePattern, playedStringSet, relabelShape, relabelShapeToScale, relatedScales, remove, removeAll, resolveArpeggioForSlot, scaleTypeForChordType, scalesContainingChord, scoreShapeMatch, sixths, slotForChordShape, sourceGripBaseFret, thirds, toAlphaTeX, toAsciiTab, visibleArpeggios, walkPattern, walkShape, walkShapeIntervals, walkShapeMotif };
1860
+ export { ASCENDING_THIRDS, type AddChange, type AlphaTexOptions, type ArpeggioResolution, type ArpeggioShape, type ArpeggioSlot, type ArpeggioTier, type AsciiTabOptions, type AuditSeverity, type Barre, CHECK_BARRE_FRET_ORIGIN, CHECK_BUILD_LOSS, CHECK_CHORD_TONES_ONLY, CHECK_CONTAINS_CHORD_GRIP, CHECK_COVERS_CHORD, CHECK_FINGERING_COMPLETE, CHECK_FINGER_ZERO_ON_MOVABLE, CHECK_FRET_SPAN, CHECK_GEOMETRY_MISMATCH, CHECK_IDENTIFY_MISMATCH, CHECK_METADATA_COMPLETENESS, CHECK_NAME_UNIQUE, CHECK_OVERRIDES_TARGET, CHECK_POSITION_SPAN, CHECK_REPEATED_FINGER_NO_BARRE, CHECK_STRINGSET_MISMATCH, CHECK_TUNING_MISMATCH, CHORD_SCALE_RULE, CHORD_SCALE_RULE_VERSION, type CagedPosition, type ChainDirection, type Changeset, type ChangesetChange, type ChangesetKind, type ChordGeometryDetails, type ChordScaleEntry, type ChordShape, type ChordShapeAuditResult, type ConnectSequencesInput, type ConnectSequencesResult, type ConnectorOptions, type ConnectorStrategy, type ContainingScale, DADGAD, DEFAULT_SCALE_CORPUS, DESCENDING_THIRDS, DROP_D, type Fingering, type FretboardPosition, type FrettedNote, type FrettedScale, type InferenceCandidate, type InferenceInput, type InferenceOptions, type InferenceProbe, type KeyAnalysis, NoFrettedScale, OPEN_G, type PassingToneOptions, type RelabelOptions, type RemoveChange, SEQ_1234_GROUP, SEQ_1235, SEQ_1357_DESC, SEQ_TRIAD_CLIMB, SEQ_UP_DOWN, SHELL_DICTIONARY, STANDARD, STANDARD_7, STANDARD_8, type ScaleShape, type ScalesContainingChordOptions, type ScalesContainingChordResult, type ScoreBreakdown, type SequenceOptions, type ShapeAuditIssue, type ShapeAuditOptions, type UpdateChange, VERSION, type VoicingFamily, type VoicingPatternDictionary, type WalkOptions, type WalkShapeOptions, absoluteBarreFret, add, addPassingTone, all, analyzeInKey, applyChordShape, applySequence, arpeggioFor, arpeggioFromScale, arpeggioFromShape, arpeggioShapes, arpeggioSlotKey, ascendingIntervals, ascendingLinear, auditAllShapes, auditAllShapesIntegration, auditArpeggioShape, auditArpeggioShapeIntegration, auditChordShape, auditChordShapeFull, auditChordShapeIntegration, auditScaleShape, autoFingering, buildFrettedScale, buildFromScale, checkBarreFretOrigin, checkChordBuildLoss, checkChordMetadataCompleteness, checkChordTonesOnly, checkContainsChordGrip, checkCoversChord, checkFingerZeroOnMovable, checkFingeringComplete, checkFretSpan, checkGeometryMismatch, checkIdentifyMismatch, checkNameUnique, checkOverridesTarget, checkPositionSpan, checkRepeatedFingerNoBarre, checkScaleBuildLoss, checkScaleMetadataCompleteness, checkStringsetMismatch, checkTuningMismatch, chordShapeGeometry, chordShapes, connectSequences, descendingIntervals, descendingLinear, displayRootFor, exportIdentifierFor, filterChordTones, findFretInPosition, findNearestFret, findNote, flattenSequence, formatChordFrets, fourths, fretFor, fretboard, get, gripBaseFret, grouping, identifyChord, impliedStringSet, inferShapeContext, isMovable, isShapeCompatible, modeShapes, names, noteAt, parentBoxForChordShape, parseChordFrets, parseScalePattern, playedStringSet, relabelShape, relabelShapeToScale, relatedScales, remove, removeAll, resolveArpeggioForSlot, scaleTypeForChordType, scalesContainingChord, scoreShapeMatch, sixths, slotForChordShape, sourceGripBaseFret, thirds, toAlphaTeX, toAsciiTab, visibleArpeggios, walkPattern, walkShape, walkShapeIntervals, walkShapeMotif };