@leanandmean/coding-agent 0.74.1-scramjet.27 → 0.74.1-scramjet.29

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,14 +1,16 @@
1
1
  // SCRAMJET-DIVERGENCE: Removed pi.dev network code (LATEST_VERSION_URL, fetch calls);
2
2
  // renamed Pi-prefixed identifiers; network functions gutted to return undefined.
3
3
  function parsePackageVersion(version) {
4
- const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.*)?$/);
5
- if (!match) {
4
+ const match = version
5
+ .trim()
6
+ .match(/^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/);
7
+ if (!match || match[4]?.split(".").some((identifier) => /^0\d+$/.test(identifier))) {
6
8
  return undefined;
7
9
  }
8
10
  return {
9
- major: Number.parseInt(match[1], 10),
10
- minor: Number.parseInt(match[2], 10),
11
- patch: Number.parseInt(match[3], 10),
11
+ major: match[1],
12
+ minor: match[2],
13
+ patch: match[3],
12
14
  prerelease: match[4],
13
15
  };
14
16
  }
@@ -18,26 +20,49 @@ function comparePackageVersions(leftVersion, rightVersion) {
18
20
  if (!left || !right) {
19
21
  return undefined;
20
22
  }
21
- if (left.major !== right.major)
22
- return left.major - right.major;
23
- if (left.minor !== right.minor)
24
- return left.minor - right.minor;
25
- if (left.patch !== right.patch)
26
- return left.patch - right.patch;
23
+ for (const component of ["major", "minor", "patch"]) {
24
+ if (left[component] === right[component])
25
+ continue;
26
+ if (left[component].length !== right[component].length) {
27
+ return left[component].length - right[component].length;
28
+ }
29
+ return left[component].localeCompare(right[component]);
30
+ }
27
31
  if (left.prerelease === right.prerelease)
28
32
  return 0;
29
33
  if (!left.prerelease)
30
34
  return 1;
31
35
  if (!right.prerelease)
32
36
  return -1;
33
- return left.prerelease.localeCompare(right.prerelease);
37
+ const leftIdentifiers = left.prerelease.split(".");
38
+ const rightIdentifiers = right.prerelease.split(".");
39
+ for (let index = 0; index < Math.max(leftIdentifiers.length, rightIdentifiers.length); index++) {
40
+ const leftIdentifier = leftIdentifiers[index];
41
+ const rightIdentifier = rightIdentifiers[index];
42
+ if (leftIdentifier === undefined)
43
+ return -1;
44
+ if (rightIdentifier === undefined)
45
+ return 1;
46
+ if (leftIdentifier === rightIdentifier)
47
+ continue;
48
+ const leftNumeric = /^\d+$/.test(leftIdentifier);
49
+ const rightNumeric = /^\d+$/.test(rightIdentifier);
50
+ if (leftNumeric && rightNumeric) {
51
+ if (leftIdentifier.length !== rightIdentifier.length)
52
+ return leftIdentifier.length - rightIdentifier.length;
53
+ return leftIdentifier.localeCompare(rightIdentifier);
54
+ }
55
+ if (leftNumeric)
56
+ return -1;
57
+ if (rightNumeric)
58
+ return 1;
59
+ return leftIdentifier.localeCompare(rightIdentifier);
60
+ }
61
+ return 0;
34
62
  }
63
+ // SCRAMJET-DIVERGENCE: malformed package versions fail closed for passive update notifications (#432).
35
64
  export function isNewerPackageVersion(candidateVersion, currentVersion) {
36
- const comparison = comparePackageVersions(candidateVersion, currentVersion);
37
- if (comparison !== undefined) {
38
- return comparison > 0;
39
- }
40
- return candidateVersion.trim() !== currentVersion.trim();
65
+ return (comparePackageVersions(candidateVersion, currentVersion) ?? 0) > 0;
41
66
  }
42
67
  export async function getLatestRelease(_currentVersion, _options = {}) {
43
68
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"version-check.js","sourceRoot":"","sources":["../../src/utils/version-check.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,iFAAiF;AAcjF,SAAS,mBAAmB,CAAC,OAAe,EAA6B;IACxE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC7F,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO;QACN,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACpC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACpC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACpC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;KACpB,CAAC;AAAA,CACF;AAED,SAAS,sBAAsB,CAAC,WAAmB,EAAE,YAAoB,EAAsB;IAC9F,MAAM,IAAI,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAChE,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAChE,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAChE,IAAI,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC;IACnD,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC,CAAC;IACjC,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAAA,CACvD;AAED,MAAM,UAAU,qBAAqB,CAAC,gBAAwB,EAAE,cAAsB,EAAW;IAChG,MAAM,UAAU,GAAG,sBAAsB,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;IAC5E,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,UAAU,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,gBAAgB,CAAC,IAAI,EAAE,KAAK,cAAc,CAAC,IAAI,EAAE,CAAC;AAAA,CACzD;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,eAAuB,EACvB,QAAQ,GAA2B,EAAE,EACA;IACrC,OAAO,SAAS,CAAC;AAAA,CACjB","sourcesContent":["// SCRAMJET-DIVERGENCE: Removed pi.dev network code (LATEST_VERSION_URL, fetch calls);\n// renamed Pi-prefixed identifiers; network functions gutted to return undefined.\n\nexport interface LatestRelease {\n\tversion: string;\n\tpackageName?: string;\n}\n\ninterface ParsedVersion {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tprerelease?: string;\n}\n\nfunction parsePackageVersion(version: string): ParsedVersion | undefined {\n\tconst match = version.trim().match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+.*)?$/);\n\tif (!match) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tmajor: Number.parseInt(match[1], 10),\n\t\tminor: Number.parseInt(match[2], 10),\n\t\tpatch: Number.parseInt(match[3], 10),\n\t\tprerelease: match[4],\n\t};\n}\n\nfunction comparePackageVersions(leftVersion: string, rightVersion: string): number | undefined {\n\tconst left = parsePackageVersion(leftVersion);\n\tconst right = parsePackageVersion(rightVersion);\n\tif (!left || !right) {\n\t\treturn undefined;\n\t}\n\n\tif (left.major !== right.major) return left.major - right.major;\n\tif (left.minor !== right.minor) return left.minor - right.minor;\n\tif (left.patch !== right.patch) return left.patch - right.patch;\n\tif (left.prerelease === right.prerelease) return 0;\n\tif (!left.prerelease) return 1;\n\tif (!right.prerelease) return -1;\n\treturn left.prerelease.localeCompare(right.prerelease);\n}\n\nexport function isNewerPackageVersion(candidateVersion: string, currentVersion: string): boolean {\n\tconst comparison = comparePackageVersions(candidateVersion, currentVersion);\n\tif (comparison !== undefined) {\n\t\treturn comparison > 0;\n\t}\n\treturn candidateVersion.trim() !== currentVersion.trim();\n}\n\nexport async function getLatestRelease(\n\t_currentVersion: string,\n\t_options: { timeoutMs?: number } = {},\n): Promise<LatestRelease | undefined> {\n\treturn undefined;\n}\n"]}
1
+ {"version":3,"file":"version-check.js","sourceRoot":"","sources":["../../src/utils/version-check.ts"],"names":[],"mappings":"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","sourcesContent":["// SCRAMJET-DIVERGENCE: Removed pi.dev network code (LATEST_VERSION_URL, fetch calls);\n// renamed Pi-prefixed identifiers; network functions gutted to return undefined.\n\nexport interface LatestRelease {\n\tversion: string;\n\tpackageName?: string;\n}\n\ninterface ParsedVersion {\n\tmajor: string;\n\tminor: string;\n\tpatch: string;\n\tprerelease?: string;\n}\n\nfunction parsePackageVersion(version: string): ParsedVersion | undefined {\n\tconst match = version\n\t\t.trim()\n\t\t.match(\n\t\t\t/^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/,\n\t\t);\n\tif (!match || match[4]?.split(\".\").some((identifier) => /^0\\d+$/.test(identifier))) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tmajor: match[1],\n\t\tminor: match[2],\n\t\tpatch: match[3],\n\t\tprerelease: match[4],\n\t};\n}\n\nfunction comparePackageVersions(leftVersion: string, rightVersion: string): number | undefined {\n\tconst left = parsePackageVersion(leftVersion);\n\tconst right = parsePackageVersion(rightVersion);\n\tif (!left || !right) {\n\t\treturn undefined;\n\t}\n\n\tfor (const component of [\"major\", \"minor\", \"patch\"] as const) {\n\t\tif (left[component] === right[component]) continue;\n\t\tif (left[component].length !== right[component].length) {\n\t\t\treturn left[component].length - right[component].length;\n\t\t}\n\t\treturn left[component].localeCompare(right[component]);\n\t}\n\tif (left.prerelease === right.prerelease) return 0;\n\tif (!left.prerelease) return 1;\n\tif (!right.prerelease) return -1;\n\tconst leftIdentifiers = left.prerelease.split(\".\");\n\tconst rightIdentifiers = right.prerelease.split(\".\");\n\tfor (let index = 0; index < Math.max(leftIdentifiers.length, rightIdentifiers.length); index++) {\n\t\tconst leftIdentifier = leftIdentifiers[index];\n\t\tconst rightIdentifier = rightIdentifiers[index];\n\t\tif (leftIdentifier === undefined) return -1;\n\t\tif (rightIdentifier === undefined) return 1;\n\t\tif (leftIdentifier === rightIdentifier) continue;\n\t\tconst leftNumeric = /^\\d+$/.test(leftIdentifier);\n\t\tconst rightNumeric = /^\\d+$/.test(rightIdentifier);\n\t\tif (leftNumeric && rightNumeric) {\n\t\t\tif (leftIdentifier.length !== rightIdentifier.length) return leftIdentifier.length - rightIdentifier.length;\n\t\t\treturn leftIdentifier.localeCompare(rightIdentifier);\n\t\t}\n\t\tif (leftNumeric) return -1;\n\t\tif (rightNumeric) return 1;\n\t\treturn leftIdentifier.localeCompare(rightIdentifier);\n\t}\n\treturn 0;\n}\n\n// SCRAMJET-DIVERGENCE: malformed package versions fail closed for passive update notifications (#432).\nexport function isNewerPackageVersion(candidateVersion: string, currentVersion: string): boolean {\n\treturn (comparePackageVersions(candidateVersion, currentVersion) ?? 0) > 0;\n}\n\nexport async function getLatestRelease(\n\t_currentVersion: string,\n\t_options: { timeoutMs?: number } = {},\n): Promise<LatestRelease | undefined> {\n\treturn undefined;\n}\n"]}
@@ -73,10 +73,7 @@ Scramjet loads context files at startup. Add an `AGENTS.md` file to tell it how
73
73
  - Keep responses concise.
74
74
  ```
75
75
 
76
- Scramjet loads:
77
-
78
- - `~/.scramjet/agent/AGENTS.md` for global instructions
79
- - `AGENTS.md` or `CLAUDE.md` from parent directories and the current directory
76
+ Scramjet loads `CLAUDE.md` and `AGENTS.md` from the global agent directory, parent directories, and the current directory. Within each directory, `CLAUDE.md` loads first. If both files there decode to exactly equal text, only `CLAUDE.md` is loaded; equal text in different directories remains independently loaded.
80
77
 
81
78
  Restart scramjet, or run `/reload`, after changing context files.
82
79
 
package/docs/sdk.md CHANGED
@@ -365,7 +365,7 @@ const { session } = await createAgentSession({
365
365
  - `.scramjet/skills/`
366
366
  - `.agents/skills/` in `cwd` and ancestor directories (up to git repo root, or filesystem root when not in a repo)
367
367
  - Project prompts (`.scramjet/prompts/`)
368
- - Context files (`AGENTS.md` walking up from cwd)
368
+ - Context files (`CLAUDE.md` and `AGENTS.md` walking up from cwd)
369
369
  - Session directory naming
370
370
 
371
371
  `agentDir` is used by `DefaultResourceLoader` for:
@@ -374,7 +374,7 @@ const { session } = await createAgentSession({
374
374
  - `skills/` under `agentDir` (for example `~/.scramjet/agent/skills/`)
375
375
  - `~/.agents/skills/`
376
376
  - Global prompts (`prompts/`)
377
- - Global context file (`AGENTS.md`)
377
+ - Global context files (`CLAUDE.md` and `AGENTS.md`)
378
378
  - Settings (`settings.json`)
379
379
  - Custom models (`models.json`)
380
380
  - Credentials (`auth.json`)
@@ -657,6 +657,8 @@ const { session } = await createAgentSession({ resourceLoader: loader });
657
657
 
658
658
  ### Context Files
659
659
 
660
+ Default discovery loads context broadest-to-most-specific and orders `CLAUDE.md` before `AGENTS.md` within each directory. When both same-directory files decode to exactly equal text, only `CLAUDE.md` is retained; equality suppression never crosses directory boundaries.
661
+
660
662
  ```typescript
661
663
  import { createAgentSession, DefaultResourceLoader } from "@leanandmean/coding-agent";
662
664
 
package/docs/usage.md CHANGED
@@ -92,13 +92,13 @@ See [Sessions](sessions.md) and [Compaction](compaction.md) for details.
92
92
 
93
93
  ## Context Files
94
94
 
95
- Scramjet loads `AGENTS.md` or `CLAUDE.md` at startup from:
95
+ Scramjet loads `CLAUDE.md` and `AGENTS.md` at startup from:
96
96
 
97
- - `~/.scramjet/agent/AGENTS.md` for global instructions
97
+ - `~/.scramjet/agent/` for global instructions
98
98
  - parent directories, walking up from the current working directory
99
99
  - the current directory
100
100
 
101
- Use context files for project conventions, commands, safety rules, and preferences. Disable loading with `--no-context-files` or `-nc`.
101
+ Files load broadest-to-most-specific, with `CLAUDE.md` before `AGENTS.md` in each directory. When both names in one directory decode to exactly equal text, only `CLAUDE.md` is loaded; equality suppression never crosses directory boundaries. Use context files for project conventions, commands, safety rules, and preferences. Disable loading with `--no-context-files` or `-nc`.
102
102
 
103
103
  ### System Prompt Files
104
104
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanandmean/coding-agent",
3
- "version": "0.74.1-scramjet.27",
3
+ "version": "0.74.1-scramjet.29",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },