@miranda0808/maya-codex 0.1.0 → 0.1.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,38 +1,94 @@
1
- $ErrorActionPreference = 'Stop'
2
- Set-ExecutionPolicy -Scope Process Bypass -Force
3
-
4
- $wrapper = Join-Path $PSScriptRoot 'meta-fetch.ps1'
5
-
6
- if (-not (Test-Path $wrapper)) {
7
- throw 'meta-fetch.ps1 is missing'
8
- }
9
-
10
- $oldToken = $env:META_ACCESS_TOKEN
11
- $oldAccount = $env:META_AD_ACCOUNT_ID
12
- $env:META_ACCESS_TOKEN = 'super-secret-token'
13
- $env:META_AD_ACCOUNT_ID = '1234567890'
14
-
15
- try {
16
- $output = & $wrapper -Resource campaigns -Action list -DryRun 2>&1
17
- $text = ($output | Out-String)
18
-
19
- if ($LASTEXITCODE -ne 0) {
20
- throw "Expected dry run to succeed but exit code was $LASTEXITCODE. Output: $text"
21
- }
22
-
23
- if ($text -match 'super-secret-token') {
24
- throw 'Dry run output leaked META_ACCESS_TOKEN'
25
- }
26
-
27
- if ($text -notmatch '"dry_run"\s*:\s*true') {
28
- throw "Expected dry_run marker in output. Output: $text"
29
- }
30
-
31
- if ($text -notmatch '"cache_status"\s*:\s*"miss"') {
32
- throw "Expected cache_status miss marker in dry-run output. Output: $text"
33
- }
34
- }
35
- finally {
36
- $env:META_ACCESS_TOKEN = $oldToken
37
- $env:META_AD_ACCOUNT_ID = $oldAccount
38
- }
1
+ $ErrorActionPreference = 'Stop'
2
+ Set-ExecutionPolicy -Scope Process Bypass -Force
3
+
4
+ $wrapper = Join-Path $PSScriptRoot 'meta-fetch.ps1'
5
+
6
+ if (-not (Test-Path $wrapper)) {
7
+ throw 'meta-fetch.ps1 is missing'
8
+ }
9
+
10
+ $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
11
+ $envFile = Join-Path $repoRoot '.env'
12
+ $envLocalFile = Join-Path $repoRoot '.env.local'
13
+ $oldToken = $env:META_ACCESS_TOKEN
14
+ $oldAccount = $env:META_AD_ACCOUNT_ID
15
+ $oldEnvFile = if (Test-Path $envFile) { Get-Content $envFile -Raw } else { $null }
16
+ $oldEnvLocalFile = if (Test-Path $envLocalFile) { Get-Content $envLocalFile -Raw } else { $null }
17
+ $hadToken = Test-Path Env:META_ACCESS_TOKEN
18
+ $hadAccount = Test-Path Env:META_AD_ACCOUNT_ID
19
+
20
+ $env:META_ACCESS_TOKEN = 'super-secret-token'
21
+ $env:META_AD_ACCOUNT_ID = '1234567890'
22
+
23
+ try {
24
+ $output = & $wrapper -Resource campaigns -Action list -DryRun 2>&1
25
+ $text = ($output | Out-String)
26
+
27
+ if ($LASTEXITCODE -ne 0) {
28
+ throw "Expected dry run to succeed but exit code was $LASTEXITCODE. Output: $text"
29
+ }
30
+
31
+ if ($text -match 'super-secret-token') {
32
+ throw 'Dry run output leaked META_ACCESS_TOKEN'
33
+ }
34
+
35
+ if ($text -notmatch '"dry_run"\s*:\s*true') {
36
+ throw "Expected dry_run marker in output. Output: $text"
37
+ }
38
+
39
+ if ($text -notmatch '"cache_status"\s*:\s*"miss"') {
40
+ throw "Expected cache_status miss marker in dry-run output. Output: $text"
41
+ }
42
+
43
+ Remove-Item Env:META_ACCESS_TOKEN -ErrorAction SilentlyContinue
44
+ Remove-Item Env:META_AD_ACCOUNT_ID -ErrorAction SilentlyContinue
45
+ Set-Content -Path $envFile -Value "META_ACCESS_TOKEN=env-file-token`nMETA_AD_ACCOUNT_ID=11112222`n"
46
+
47
+ $envFromFile = & $wrapper -Resource campaigns -Action list -DryRun 2>&1
48
+ $envFromFileText = ($envFromFile | Out-String)
49
+
50
+ if ($LASTEXITCODE -ne 0) {
51
+ throw "Expected .env-backed dry run to succeed but exit code was $LASTEXITCODE. Output: $envFromFileText"
52
+ }
53
+
54
+ if ($envFromFileText -notmatch '"safe_account_alias"\s*:\s*"acct-\*\*\*2222"') {
55
+ throw "Expected .env-backed account alias in output. Output: $envFromFileText"
56
+ }
57
+
58
+ Set-Content -Path $envLocalFile -Value "META_ACCESS_TOKEN=env-local-token`nMETA_AD_ACCOUNT_ID=99990000`n"
59
+ $envLocalOutput = & $wrapper -Resource campaigns -Action list -DryRun 2>&1
60
+ $envLocalText = ($envLocalOutput | Out-String)
61
+
62
+ if ($LASTEXITCODE -ne 0) {
63
+ throw "Expected .env.local-backed dry run to succeed but exit code was $LASTEXITCODE. Output: $envLocalText"
64
+ }
65
+
66
+ if ($envLocalText -notmatch '"safe_account_alias"\s*:\s*"acct-\*\*\*0000"') {
67
+ throw "Expected .env.local to override .env values. Output: $envLocalText"
68
+ }
69
+ }
70
+ finally {
71
+ if ($hadToken) {
72
+ $env:META_ACCESS_TOKEN = $oldToken
73
+ } else {
74
+ Remove-Item Env:META_ACCESS_TOKEN -ErrorAction SilentlyContinue
75
+ }
76
+
77
+ if ($hadAccount) {
78
+ $env:META_AD_ACCOUNT_ID = $oldAccount
79
+ } else {
80
+ Remove-Item Env:META_AD_ACCOUNT_ID -ErrorAction SilentlyContinue
81
+ }
82
+
83
+ if ($null -eq $oldEnvFile) {
84
+ Remove-Item $envFile -ErrorAction SilentlyContinue
85
+ } else {
86
+ Set-Content -Path $envFile -Value $oldEnvFile -NoNewline
87
+ }
88
+
89
+ if ($null -eq $oldEnvLocalFile) {
90
+ Remove-Item $envLocalFile -ErrorAction SilentlyContinue
91
+ } else {
92
+ Set-Content -Path $envLocalFile -Value $oldEnvLocalFile -NoNewline
93
+ }
94
+ }
@@ -1,13 +1,14 @@
1
- {
2
- "files": [
3
- "MAYA.md",
4
- "MAYA-CATALOG.md",
5
- "MAYA-DEPENDENCIES.md",
6
- "commands",
7
- ".maya",
8
- "templates",
9
- "campaigns/README.md",
10
- "research/README.md",
11
- "tools"
12
- ]
13
- }
1
+ {
2
+ "files": [
3
+ "MAYA.md",
4
+ "MAYA-CATALOG.md",
5
+ "MAYA-DEPENDENCIES.md",
6
+ ".env.example",
7
+ "commands",
8
+ ".maya",
9
+ "templates",
10
+ "campaigns/README.md",
11
+ "research/README.md",
12
+ "tools"
13
+ ]
14
+ }
@@ -1,105 +1,136 @@
1
- "use strict";
2
-
3
- const { access, copyFile, mkdir, readdir, readFile, stat, writeFile } = require("node:fs/promises");
4
- const path = require("node:path");
5
-
6
- function toPosixPath(value) {
7
- return value.split(path.sep).join("/");
8
- }
9
-
10
- function fromPosixPath(basePath, relativePath) {
11
- const segments = relativePath.split("/").filter(Boolean);
12
- return path.join(basePath, ...segments);
13
- }
14
-
15
- function joinPosixPath(...segments) {
16
- return segments.filter(Boolean).join("/").replace(/\/+/g, "/");
17
- }
18
-
19
- function resolveTargetDirectory(options = {}) {
20
- const cwd = options.cwd || process.cwd();
21
- const target = options.target || ".";
22
-
23
- return path.resolve(cwd, target);
24
- }
25
-
26
- async function pathExists(targetPath) {
27
- try {
28
- await access(targetPath);
29
- return true;
30
- } catch (error) {
31
- if (error && error.code === "ENOENT") {
32
- return false;
33
- }
34
-
35
- throw error;
36
- }
37
- }
38
-
39
- async function assertExistingDirectory(targetPath) {
40
- let details;
41
-
42
- try {
43
- details = await stat(targetPath);
44
- } catch (error) {
45
- if (error && error.code === "ENOENT") {
46
- throw new Error(`Target directory does not exist: ${targetPath}`);
47
- }
48
-
49
- throw error;
50
- }
51
-
52
- if (!details.isDirectory()) {
53
- throw new Error(`Target path is not a directory: ${targetPath}`);
54
- }
55
- }
56
-
57
- async function ensureDirectory(targetPath) {
58
- await mkdir(targetPath, { recursive: true });
59
- }
60
-
61
- async function listFilesRecursive(rootPath, currentRelative = "") {
62
- const entries = await readdir(rootPath, { withFileTypes: true });
63
- const files = [];
64
-
65
- for (const entry of entries) {
66
- const entryRelative = currentRelative ? joinPosixPath(currentRelative, entry.name) : entry.name;
67
- const entryPath = path.join(rootPath, entry.name);
68
-
69
- if (entry.isDirectory()) {
70
- files.push(...(await listFilesRecursive(entryPath, entryRelative)));
71
- continue;
72
- }
73
-
74
- files.push(entryRelative);
75
- }
76
-
77
- return files.sort();
78
- }
79
-
80
- function normalizeLineEndings(content) {
81
- return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
82
- }
83
-
84
- async function writeTextFile(targetPath, content) {
85
- await writeFile(targetPath, normalizeLineEndings(content), "utf8");
86
- }
87
-
88
- async function copyOpaqueFile(sourcePath, destinationPath) {
89
- await copyFile(sourcePath, destinationPath);
90
- }
91
-
92
- module.exports = {
93
- assertExistingDirectory,
94
- copyOpaqueFile,
95
- ensureDirectory,
96
- fromPosixPath,
97
- joinPosixPath,
98
- listFilesRecursive,
99
- normalizeLineEndings,
100
- pathExists,
101
- readFile,
102
- resolveTargetDirectory,
103
- toPosixPath,
104
- writeTextFile,
105
- };
1
+ "use strict";
2
+
3
+ const { access, copyFile, mkdir, readdir, readFile, stat, writeFile } = require("node:fs/promises");
4
+ const path = require("node:path");
5
+
6
+ function toPosixPath(value) {
7
+ return value.split(path.sep).join("/");
8
+ }
9
+
10
+ function fromPosixPath(basePath, relativePath) {
11
+ const segments = relativePath.split("/").filter(Boolean);
12
+ return path.join(basePath, ...segments);
13
+ }
14
+
15
+ function joinPosixPath(...segments) {
16
+ return segments.filter(Boolean).join("/").replace(/\/+/g, "/");
17
+ }
18
+
19
+ function resolveTargetDirectory(options = {}) {
20
+ const cwd = options.cwd || process.cwd();
21
+ const target = options.target || ".";
22
+
23
+ return path.resolve(cwd, target);
24
+ }
25
+
26
+ async function pathExists(targetPath) {
27
+ try {
28
+ await access(targetPath);
29
+ return true;
30
+ } catch (error) {
31
+ if (error && error.code === "ENOENT") {
32
+ return false;
33
+ }
34
+
35
+ throw error;
36
+ }
37
+ }
38
+
39
+ async function assertExistingDirectory(targetPath) {
40
+ let details;
41
+
42
+ try {
43
+ details = await stat(targetPath);
44
+ } catch (error) {
45
+ if (error && error.code === "ENOENT") {
46
+ throw new Error(`Target directory does not exist: ${targetPath}`);
47
+ }
48
+
49
+ throw error;
50
+ }
51
+
52
+ if (!details.isDirectory()) {
53
+ throw new Error(`Target path is not a directory: ${targetPath}`);
54
+ }
55
+ }
56
+
57
+ async function ensureDirectory(targetPath) {
58
+ await mkdir(targetPath, { recursive: true });
59
+ }
60
+
61
+ async function listFilesRecursive(rootPath, currentRelative = "") {
62
+ const entries = await readdir(rootPath, { withFileTypes: true });
63
+ const files = [];
64
+
65
+ for (const entry of entries) {
66
+ const entryRelative = currentRelative ? joinPosixPath(currentRelative, entry.name) : entry.name;
67
+ const entryPath = path.join(rootPath, entry.name);
68
+
69
+ if (entry.isDirectory()) {
70
+ files.push(...(await listFilesRecursive(entryPath, entryRelative)));
71
+ continue;
72
+ }
73
+
74
+ files.push(entryRelative);
75
+ }
76
+
77
+ return files.sort();
78
+ }
79
+
80
+ function normalizeLineEndings(content) {
81
+ return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
82
+ }
83
+
84
+ async function writeTextFile(targetPath, content) {
85
+ await writeFile(targetPath, normalizeLineEndings(content), "utf8");
86
+ }
87
+
88
+ async function ensureGitignoreEntries(targetPath, entries) {
89
+ const exists = await pathExists(targetPath);
90
+ const currentContent = exists ? await readFile(targetPath, "utf8") : "";
91
+ const normalizedContent = normalizeLineEndings(currentContent);
92
+ const currentEntries = new Set(
93
+ normalizedContent
94
+ .split("\n")
95
+ .map((line) => line.trim())
96
+ .filter(Boolean),
97
+ );
98
+ const missingEntries = entries.filter((entry) => !currentEntries.has(entry));
99
+
100
+ if (missingEntries.length === 0) {
101
+ return { changed: false, created: false };
102
+ }
103
+
104
+ let nextContent = normalizedContent;
105
+ if (nextContent.length > 0 && !nextContent.endsWith("\n")) {
106
+ nextContent += "\n";
107
+ }
108
+ nextContent += `${missingEntries.join("\n")}\n`;
109
+
110
+ await writeTextFile(targetPath, nextContent);
111
+
112
+ return {
113
+ changed: true,
114
+ created: !exists,
115
+ };
116
+ }
117
+
118
+ async function copyOpaqueFile(sourcePath, destinationPath) {
119
+ await copyFile(sourcePath, destinationPath);
120
+ }
121
+
122
+ module.exports = {
123
+ assertExistingDirectory,
124
+ copyOpaqueFile,
125
+ ensureDirectory,
126
+ ensureGitignoreEntries,
127
+ fromPosixPath,
128
+ joinPosixPath,
129
+ listFilesRecursive,
130
+ normalizeLineEndings,
131
+ pathExists,
132
+ readFile,
133
+ resolveTargetDirectory,
134
+ toPosixPath,
135
+ writeTextFile,
136
+ };