@astryxdesign/core 0.7.2-canary.e868278 → 0.7.2-canary.f2b60a0
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/core",
|
|
3
|
-
"version": "0.7.2-canary.
|
|
3
|
+
"version": "0.7.2-canary.f2b60a0",
|
|
4
4
|
"displayName": "Astryx Core",
|
|
5
5
|
"description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -792,8 +792,8 @@
|
|
|
792
792
|
"react-dom": ">=19.0.0"
|
|
793
793
|
},
|
|
794
794
|
"devDependencies": {
|
|
795
|
-
"@astryxdesign/a11y-spec": "0.7.2-canary.
|
|
796
|
-
"@astryxdesign/cli": "0.7.2-canary.
|
|
795
|
+
"@astryxdesign/a11y-spec": "0.7.2-canary.f2b60a0",
|
|
796
|
+
"@astryxdesign/cli": "0.7.2-canary.f2b60a0",
|
|
797
797
|
"@babel/cli": "^7.29.7",
|
|
798
798
|
"@babel/core": "^7.29.7",
|
|
799
799
|
"@babel/preset-react": "^7.29.7",
|
|
@@ -106,6 +106,44 @@ export function isAstryxInitialized(targetDir = process.cwd()) {
|
|
|
106
106
|
return false;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Does an agent working in `startDir` already have the Astryx prompt in reach?
|
|
111
|
+
*
|
|
112
|
+
* Coding agents read the agent docs between the repository root and the folder
|
|
113
|
+
* they work in. So inside a git repository, init's block in any folder from
|
|
114
|
+
* `startDir` up to the repository root counts: a workspace package of a
|
|
115
|
+
* monorepo initialized at its root is set up. Outside a repository only
|
|
116
|
+
* `startDir` itself is checked, as {@link isAstryxInitialized} does. Both the
|
|
117
|
+
* per-command nudge and the postinstall nudges ask this.
|
|
118
|
+
*
|
|
119
|
+
* @param {string} [startDir=process.cwd()]
|
|
120
|
+
* @returns {boolean}
|
|
121
|
+
*/
|
|
122
|
+
export function isAstryxPromptInReach(startDir = process.cwd()) {
|
|
123
|
+
const start = path.resolve(startDir);
|
|
124
|
+
const repositoryRoot = findRepositoryRoot(start);
|
|
125
|
+
if (!repositoryRoot) return isAstryxInitialized(start);
|
|
126
|
+
for (let dir = start; ; dir = path.dirname(dir)) {
|
|
127
|
+
if (isAstryxInitialized(dir)) return true;
|
|
128
|
+
if (dir === repositoryRoot) return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The nearest folder at or above `start` that holds `.git` (a folder, or the
|
|
134
|
+
* file a worktree uses), or null outside a repository.
|
|
135
|
+
* @param {string} start
|
|
136
|
+
* @returns {string | null}
|
|
137
|
+
*/
|
|
138
|
+
function findRepositoryRoot(start) {
|
|
139
|
+
for (let dir = start; ; ) {
|
|
140
|
+
if (fs.existsSync(path.join(dir, '.git'))) return dir;
|
|
141
|
+
const parent = path.dirname(dir);
|
|
142
|
+
if (parent === dir) return null;
|
|
143
|
+
dir = parent;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
109
147
|
/**
|
|
110
148
|
* The one-line next-step both postinstall nudges print. Kept here so layer 1
|
|
111
149
|
* (core) and layer 2 (cli) can never word it differently.
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -45,7 +45,7 @@ async function main() {
|
|
|
45
45
|
contract.shouldNudge({
|
|
46
46
|
scriptPath: HERE,
|
|
47
47
|
npmCommand: process.env.npm_command,
|
|
48
|
-
isSetUp: contract.
|
|
48
|
+
isSetUp: contract.isAstryxPromptInReach(root),
|
|
49
49
|
})
|
|
50
50
|
) {
|
|
51
51
|
process.stdout.write(contract.SETUP_NUDGE);
|
package/src/postinstall.test.mjs
CHANGED
|
@@ -11,12 +11,15 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {describe, it, expect, beforeEach, afterEach} from 'vitest';
|
|
14
|
+
import {spawnSync} from 'node:child_process';
|
|
14
15
|
import * as fs from 'node:fs';
|
|
15
16
|
import * as os from 'node:os';
|
|
16
17
|
import * as path from 'node:path';
|
|
18
|
+
import {fileURLToPath} from 'node:url';
|
|
17
19
|
// Core's own package-local contract copy — what actually runs at install time.
|
|
18
20
|
import {
|
|
19
21
|
isAstryxInitialized,
|
|
22
|
+
isAstryxPromptInReach,
|
|
20
23
|
shouldNudge,
|
|
21
24
|
AGENT_DOC_PATHS,
|
|
22
25
|
INIT_MARKERS,
|
|
@@ -98,6 +101,49 @@ describe('core postinstall — one authoritative source, no drift', () => {
|
|
|
98
101
|
write('AGENTS.md', `# doc\n${MARKER}\nbody`);
|
|
99
102
|
expect(isAstryxInitialized(tmp)).toBe(cliLeaf.isAstryxInitialized(tmp));
|
|
100
103
|
});
|
|
104
|
+
|
|
105
|
+
it('agrees with the CLI leaf on a monorepo package', () => {
|
|
106
|
+
fs.mkdirSync(path.join(tmp, '.git'));
|
|
107
|
+
write('AGENTS.md', MARKER);
|
|
108
|
+
write('packages/app/package.json', '{"name":"app"}');
|
|
109
|
+
const app = path.join(tmp, 'packages/app');
|
|
110
|
+
expect(isAstryxPromptInReach(app)).toBe(true);
|
|
111
|
+
expect(isAstryxPromptInReach(app)).toBe(cliLeaf.isAstryxPromptInReach(app));
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Install time, end to end: core's real script and its contract copy, installed
|
|
116
|
+
// under a monorepo's node_modules, run the way npm runs them for a package.
|
|
117
|
+
describe('core postinstall — inside a monorepo package', () => {
|
|
118
|
+
const CORE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
119
|
+
const install = () => {
|
|
120
|
+
const installed = path.join(tmp, 'node_modules/@astryxdesign/core/scripts');
|
|
121
|
+
fs.mkdirSync(installed, {recursive: true});
|
|
122
|
+
for (const file of ['postinstall.mjs', 'agent-doc-state.mjs']) {
|
|
123
|
+
fs.copyFileSync(path.join(CORE, 'scripts', file), path.join(installed, file));
|
|
124
|
+
}
|
|
125
|
+
return spawnSync(process.execPath, [path.join(installed, 'postinstall.mjs')], {
|
|
126
|
+
env: {...process.env, INIT_CWD: path.join(tmp, 'packages/app'), npm_command: 'install'},
|
|
127
|
+
encoding: 'utf8',
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
beforeEach(() => {
|
|
131
|
+
fs.mkdirSync(path.join(tmp, '.git'));
|
|
132
|
+
write('packages/app/package.json', '{"name":"app"}');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('stays quiet when init ran at the repository root', () => {
|
|
136
|
+
write('AGENTS.md', MARKER);
|
|
137
|
+
const r = install();
|
|
138
|
+
expect(r.status).toBe(0);
|
|
139
|
+
expect(r.stdout).toBe('');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('still nudges when no folder up to the repository root ran init', () => {
|
|
143
|
+
const r = install();
|
|
144
|
+
expect(r.status).toBe(0);
|
|
145
|
+
expect(r.stdout).toMatch(/finish setup and install the Astryx agent prompt/);
|
|
146
|
+
});
|
|
101
147
|
});
|
|
102
148
|
|
|
103
149
|
describe('core postinstall — shouldNudge', () => {
|