@t275005746/gse 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.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +42 -42
- package/.github/ISSUE_TEMPLATE/change_request.yml +50 -50
- package/.github/ISSUE_TEMPLATE/config.yml +5 -5
- package/.github/PULL_REQUEST_TEMPLATE.md +38 -38
- package/.github/workflows/validate-gse.yml +33 -33
- package/.gse/README.md +18 -18
- package/.gse/gse-development-protocol.md +50 -50
- package/.gse/project-profile.md +29 -29
- package/.gse/quality-gates.md +25 -25
- package/.gse/releases/public-registry-publication-npm.md +49 -0
- package/.gse/releases/public-release-owner-required.md +65 -65
- package/.gse/releases/public-security-contact-owner-required.md +45 -45
- package/.gse/state.json +3 -4
- package/CHANGELOG.md +24 -24
- package/CONTRIBUTING.md +64 -64
- package/LICENSE +21 -21
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/SECURITY.md +41 -41
- package/SUPPORT.md +38 -38
- package/assets/marketplace/README.md +7 -7
- package/assets/marketplace/gse-listing.json +75 -75
- package/assets/templates/acceptance-execution-packet.md +73 -73
- package/assets/templates/adr.md +14 -14
- package/assets/templates/change-brief.md +16 -16
- package/assets/templates/design.md +18 -18
- package/assets/templates/dispatch-packet.md +104 -104
- package/assets/templates/evidence.md +14 -14
- package/assets/templates/execution-quality-pack.md +65 -65
- package/assets/templates/goal-map.md +21 -21
- package/assets/templates/host-adapter.md +48 -48
- package/assets/templates/host-ui-invocation-record.md +42 -42
- package/assets/templates/incident-review.md +60 -60
- package/assets/templates/public-channel-publication-record.md +49 -49
- package/assets/templates/public-ci-run-record.md +53 -53
- package/assets/templates/public-release-record.md +65 -65
- package/assets/templates/public-repository-settings-record.md +59 -59
- package/assets/templates/public-security-contact-record.md +45 -45
- package/assets/templates/release-trust-record.md +32 -32
- package/assets/templates/review.md +18 -18
- package/assets/templates/spec.md +16 -16
- package/assets/templates/target-adoption-evidence.md +29 -29
- package/assets/templates/tasks.md +17 -17
- package/assets/templates/update-release-acceptance-record.md +58 -58
- package/examples/README.md +22 -22
- package/examples/agent-runtime-host/.claude/gse-adapter.md +6 -6
- package/examples/agent-runtime-host/.codex/gse-adapter.md +7 -7
- package/examples/agent-runtime-host/.gse/goal-map.md +7 -7
- package/examples/agent-runtime-host/.gse/project-profile.md +27 -27
- package/examples/agent-runtime-host/.gse/tooling.md +5 -5
- package/examples/agent-runtime-host/.mcp.json +9 -9
- package/examples/agent-runtime-host/AGENTS.md +5 -5
- package/examples/agent-runtime-host/README.md +10 -10
- package/examples/agent-runtime-host/docs/model-routing.md +5 -5
- package/examples/cli-tool/.gse/project-profile.md +21 -21
- package/examples/cli-tool/AGENTS.md +5 -5
- package/examples/cli-tool/README.md +12 -12
- package/examples/cli-tool/package.json +21 -21
- package/examples/small-app/.env.example +2 -2
- package/examples/small-app/.github/workflows/ci.yml +8 -8
- package/examples/small-app/AGENTS.md +5 -5
- package/examples/small-app/README.md +12 -12
- package/examples/small-app/package.json +26 -26
- package/examples/small-app/playwright.config.ts +4 -4
- package/package.json +53 -53
- package/references/adoption-recipes.md +171 -171
- package/references/agent-roles.md +49 -49
- package/references/architecture-health.md +101 -101
- package/references/benchmark-audit.md +73 -73
- package/references/community-channels.md +46 -46
- package/references/compatibility.md +70 -70
- package/references/design-basis.md +38 -38
- package/references/domain-model.md +129 -129
- package/references/domain-quality-gates.md +75 -75
- package/references/drift-audit.md +81 -81
- package/references/evidence-taxonomy.md +123 -123
- package/references/file-ownership.md +107 -107
- package/references/final-readiness.md +84 -84
- package/references/forward-test.md +133 -133
- package/references/goal-map.md +36 -36
- package/references/host-adapters.md +119 -119
- package/references/learning-system.md +35 -35
- package/references/marketplace-discovery.md +46 -46
- package/references/model-routing.md +103 -103
- package/references/open-source-defaults.md +39 -39
- package/references/operating-model.md +52 -52
- package/references/packaging.md +277 -277
- package/references/project-agent-workspace.md +89 -89
- package/references/project-bootstrap.md +122 -122
- package/references/project-profile.md +57 -57
- package/references/public-release.md +174 -174
- package/references/quality-gates.md +100 -100
- package/references/recovery.md +176 -176
- package/references/release-trust.md +43 -43
- package/references/release.md +126 -126
- package/references/review.md +141 -141
- package/references/router.md +90 -90
- package/references/spec-workflow.md +66 -66
- package/references/task-levels.md +81 -81
- package/references/tool-adapters.md +73 -73
- package/scripts/audit-acceptance-execution-packet.mjs +133 -133
- package/scripts/audit-adoption-recipes.mjs +99 -99
- package/scripts/audit-change-lifecycle.mjs +77 -77
- package/scripts/audit-change-system.mjs +134 -134
- package/scripts/audit-ci-readiness.mjs +107 -107
- package/scripts/audit-close-gate.mjs +323 -323
- package/scripts/audit-command-adapters.mjs +91 -91
- package/scripts/audit-command-execution.mjs +210 -210
- package/scripts/audit-compatibility.mjs +149 -149
- package/scripts/audit-completion-readiness.mjs +292 -292
- package/scripts/audit-distribution.mjs +251 -251
- package/scripts/audit-domain-quality-gates.mjs +108 -108
- package/scripts/audit-evidence-placeholders.mjs +126 -126
- package/scripts/audit-final-readiness-promotion.mjs +255 -255
- package/scripts/audit-final-readiness.mjs +226 -226
- package/scripts/audit-fixtures.mjs +154 -154
- package/scripts/audit-fresh-session-readiness.mjs +177 -177
- package/scripts/audit-host-runtime-evidence-handoff.mjs +159 -159
- package/scripts/audit-host-runtime-invocation-drill.mjs +240 -240
- package/scripts/audit-host-runtime-invocations.mjs +254 -254
- package/scripts/audit-host-ui-invocation.mjs +132 -132
- package/scripts/audit-marketplace-discovery.mjs +122 -122
- package/scripts/audit-npm-package-metadata.mjs +155 -155
- package/scripts/audit-npm-publish-dry-run.mjs +191 -169
- package/scripts/audit-npm-tarball-install.mjs +191 -191
- package/scripts/audit-open-source-defaults.mjs +92 -92
- package/scripts/audit-open-source-readiness.mjs +97 -97
- package/scripts/audit-project.mjs +138 -138
- package/scripts/audit-public-acceptance-command-dry-run-drill.mjs +203 -203
- package/scripts/audit-public-acceptance-readiness.mjs +224 -224
- package/scripts/audit-public-channel-publication.mjs +248 -248
- package/scripts/audit-public-ci-run.mjs +184 -184
- package/scripts/audit-public-collaboration-templates.mjs +98 -98
- package/scripts/audit-public-external-gate-probe.mjs +206 -206
- package/scripts/audit-public-release-decision.mjs +201 -201
- package/scripts/audit-public-release-metadata.mjs +176 -176
- package/scripts/audit-public-repository-settings.mjs +237 -237
- package/scripts/audit-public-security-contact.mjs +171 -171
- package/scripts/audit-readme-docs.mjs +6 -4
- package/scripts/audit-recovery-readiness.mjs +98 -98
- package/scripts/audit-release-readiness.mjs +106 -106
- package/scripts/audit-release-trust.mjs +62 -62
- package/scripts/audit-remote-distribution.mjs +266 -266
- package/scripts/audit-roadmap-consistency.mjs +235 -235
- package/scripts/audit-signing.mjs +147 -147
- package/scripts/audit-state-freshness.mjs +14 -9
- package/scripts/audit-target-adoption-evidence.mjs +117 -117
- package/scripts/audit-target-project.mjs +507 -507
- package/scripts/audit-update-release-acceptance.mjs +136 -136
- package/scripts/audit-v1-target-validation.mjs +269 -269
- package/scripts/audit-validation-profiles.mjs +125 -125
- package/scripts/close-change.mjs +116 -116
- package/scripts/discover-project-profile.mjs +307 -307
- package/scripts/generate-command-adapter.mjs +231 -231
- package/scripts/generate-final-acceptance-packet.mjs +181 -181
- package/scripts/generate-final-form-progress-report.mjs +205 -205
- package/scripts/generate-host-runtime-evidence-handoff.mjs +206 -206
- package/scripts/generate-owner-external-gate-kit.mjs +295 -295
- package/scripts/generate-public-acceptance-handoff.mjs +168 -168
- package/scripts/generate-public-release-checklist.mjs +207 -207
- package/scripts/generate-release-bundle.mjs +505 -505
- package/scripts/generate-release-owner-action-plan.mjs +172 -172
- package/scripts/generate-release-status-manifest.mjs +200 -200
- package/scripts/generate-session-prompt.mjs +188 -188
- package/scripts/gse.mjs +67 -67
- package/scripts/init-change.mjs +265 -265
- package/scripts/init-project.mjs +785 -785
- package/scripts/install-gse.mjs +234 -234
- package/scripts/lib/evidence-placeholders.mjs +28 -28
- package/scripts/package-gse.mjs +174 -174
- package/scripts/probe-public-external-gates.mjs +167 -167
- package/scripts/record-host-invocation.mjs +151 -151
- package/scripts/record-public-channel-publication.mjs +178 -178
- package/scripts/record-public-ci-run.mjs +180 -180
- package/scripts/record-public-release.mjs +175 -175
- package/scripts/record-public-repository-settings.mjs +209 -209
- package/scripts/record-public-security-contact.mjs +157 -157
- package/scripts/sign-gse-package.mjs +83 -83
- package/scripts/update-project-state.mjs +223 -223
- package/scripts/verify-gse-package.mjs +85 -85
package/scripts/package-gse.mjs
CHANGED
|
@@ -1,174 +1,174 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import fs from 'node:fs'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import crypto from 'node:crypto'
|
|
5
|
-
|
|
6
|
-
const args = process.argv.slice(2)
|
|
7
|
-
|
|
8
|
-
function readArg(name, fallback = null) {
|
|
9
|
-
const index = args.indexOf(name)
|
|
10
|
-
if (index === -1) return fallback
|
|
11
|
-
return args[index + 1] ?? fallback
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
|
|
15
|
-
const label = readArg('--label', 'gse-local-' + new Date().toISOString().slice(0, 10))
|
|
16
|
-
const out = path.resolve(readArg('--out', path.join(process.env.TEMP || process.env.TMP || root, label)))
|
|
17
|
-
const force = args.includes('--force')
|
|
18
|
-
const dryRun = args.includes('--dry-run')
|
|
19
|
-
const jsonOnly = args.includes('--json')
|
|
20
|
-
|
|
21
|
-
const include = [
|
|
22
|
-
'package.json',
|
|
23
|
-
'SKILL.md',
|
|
24
|
-
'README.md',
|
|
25
|
-
'README.zh-CN.md',
|
|
26
|
-
'CHANGELOG.md',
|
|
27
|
-
'CONTRIBUTING.md',
|
|
28
|
-
'LICENSE',
|
|
29
|
-
'SECURITY.md',
|
|
30
|
-
'SUPPORT.md',
|
|
31
|
-
'.github',
|
|
32
|
-
'agents',
|
|
33
|
-
'assets',
|
|
34
|
-
'examples',
|
|
35
|
-
'references',
|
|
36
|
-
'scripts',
|
|
37
|
-
'.gse',
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
const excludeNames = new Set(['.git', 'node_modules', 'dist', '.DS_Store'])
|
|
41
|
-
const packageGseAllowlist = new Set([
|
|
42
|
-
'.gse/README.md',
|
|
43
|
-
'.gse/project-profile.md',
|
|
44
|
-
'.gse/quality-gates.md',
|
|
45
|
-
'.gse/gse-development-protocol.md',
|
|
46
|
-
'.gse/state.json',
|
|
47
|
-
'.gse/releases',
|
|
48
|
-
'.gse/releases/public-release-owner-required.md',
|
|
49
|
-
'.gse/releases/public-security-contact-owner-required.md',
|
|
50
|
-
])
|
|
51
|
-
const excludeRelativePrefixes = [
|
|
52
|
-
'.gse/evidence/',
|
|
53
|
-
'.gse/benchmark-audits/',
|
|
54
|
-
'.gse/acceptance/',
|
|
55
|
-
'.gse/archive/',
|
|
56
|
-
'.gse/changes/',
|
|
57
|
-
'.gse/release-bundles/',
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
function exists(relativePath) {
|
|
61
|
-
return fs.existsSync(path.join(root, relativePath))
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function shouldExclude(relativePath) {
|
|
65
|
-
const normalized = relativePath.replace(/\\/g, '/')
|
|
66
|
-
if (normalized.startsWith('.gse/') && !packageGseAllowlist.has(normalized)) return true
|
|
67
|
-
if (excludeRelativePrefixes.some((prefix) => normalized.startsWith(prefix))) return true
|
|
68
|
-
return normalized.split('/').some((part) => excludeNames.has(part))
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function walk(sourcePath, basePath = sourcePath) {
|
|
72
|
-
const entries = []
|
|
73
|
-
if (!fs.existsSync(sourcePath)) return entries
|
|
74
|
-
const stat = fs.statSync(sourcePath)
|
|
75
|
-
if (stat.isFile()) {
|
|
76
|
-
const relativePath = path.relative(root, sourcePath).replace(/\\/g, '/')
|
|
77
|
-
if (!shouldExclude(relativePath)) entries.push({ sourcePath, relativePath, bytes: stat.size })
|
|
78
|
-
return entries
|
|
79
|
-
}
|
|
80
|
-
for (const child of fs.readdirSync(sourcePath, { withFileTypes: true })) {
|
|
81
|
-
const fullPath = path.join(sourcePath, child.name)
|
|
82
|
-
const relativePath = path.relative(root, fullPath).replace(/\\/g, '/')
|
|
83
|
-
if (shouldExclude(relativePath)) continue
|
|
84
|
-
if (child.isDirectory()) entries.push(...walk(fullPath, basePath))
|
|
85
|
-
else if (child.isFile()) entries.push({ sourcePath: fullPath, relativePath, bytes: fs.statSync(fullPath).size })
|
|
86
|
-
}
|
|
87
|
-
return entries
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function copyFile(entry) {
|
|
91
|
-
const targetPath = path.join(out, entry.relativePath)
|
|
92
|
-
fs.mkdirSync(path.dirname(targetPath), { recursive: true })
|
|
93
|
-
fs.copyFileSync(entry.sourcePath, targetPath)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function sha256(filePath) {
|
|
97
|
-
return crypto.createHash('sha256').update(fs.readFileSync(filePath)).digest('hex')
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const missing = include.filter((item) => !exists(item))
|
|
101
|
-
const files = include.flatMap((item) => walk(path.join(root, item)))
|
|
102
|
-
const sortedFiles = files.map((item) => item.relativePath).sort()
|
|
103
|
-
const fileHashes = Object.fromEntries(
|
|
104
|
-
sortedFiles.map((relativePath) => [relativePath, sha256(path.join(root, relativePath))]),
|
|
105
|
-
)
|
|
106
|
-
const manifest = {
|
|
107
|
-
schemaVersion: 1,
|
|
108
|
-
packageName: 'gse',
|
|
109
|
-
label,
|
|
110
|
-
generatedAt: new Date().toISOString(),
|
|
111
|
-
fileCount: files.length,
|
|
112
|
-
totalBytes: files.reduce((sum, item) => sum + item.bytes, 0),
|
|
113
|
-
includes: include,
|
|
114
|
-
excludes: [...excludeNames, ...excludeRelativePrefixes, '.gse/* except portable package allowlist'],
|
|
115
|
-
packageGseAllowlist: [...packageGseAllowlist].sort(),
|
|
116
|
-
entrypoints: {
|
|
117
|
-
nodePackage: 'package.json',
|
|
118
|
-
skill: 'SKILL.md',
|
|
119
|
-
cli: 'scripts/gse.mjs',
|
|
120
|
-
validate: 'scripts/validate-gse.mjs',
|
|
121
|
-
npmPackageAudit: 'scripts/audit-npm-package-metadata.mjs',
|
|
122
|
-
validationProfile: 'scripts/run-validation-profile.mjs',
|
|
123
|
-
install: 'scripts/install-gse.mjs',
|
|
124
|
-
commands: 'references/commands.md',
|
|
125
|
-
},
|
|
126
|
-
integrity: {
|
|
127
|
-
algorithm: 'sha256',
|
|
128
|
-
},
|
|
129
|
-
files: sortedFiles,
|
|
130
|
-
fileHashes,
|
|
131
|
-
}
|
|
132
|
-
manifest.integrity.packageDigest = crypto
|
|
133
|
-
.createHash('sha256')
|
|
134
|
-
.update(JSON.stringify({ files: manifest.files, fileHashes: manifest.fileHashes }))
|
|
135
|
-
.digest('hex')
|
|
136
|
-
|
|
137
|
-
const report = {
|
|
138
|
-
root,
|
|
139
|
-
out,
|
|
140
|
-
label,
|
|
141
|
-
dryRun,
|
|
142
|
-
status: missing.length === 0 ? 'ready' : 'failed',
|
|
143
|
-
missing,
|
|
144
|
-
fileCount: files.length,
|
|
145
|
-
totalBytes: manifest.totalBytes,
|
|
146
|
-
manifestPath: path.join(out, 'gse-package-manifest.json'),
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (missing.length === 0 && !dryRun) {
|
|
150
|
-
if (fs.existsSync(out)) {
|
|
151
|
-
if (!force) {
|
|
152
|
-
report.status = 'exists'
|
|
153
|
-
report.recommendation = 'Use --force or choose another --out directory.'
|
|
154
|
-
} else {
|
|
155
|
-
fs.rmSync(out, { recursive: true, force: true })
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (report.status === 'ready') {
|
|
159
|
-
fs.mkdirSync(out, { recursive: true })
|
|
160
|
-
for (const file of files) copyFile(file)
|
|
161
|
-
fs.writeFileSync(path.join(out, 'gse-package-manifest.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf8')
|
|
162
|
-
report.status = 'written'
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
167
|
-
else {
|
|
168
|
-
console.log('GSE package status: ' + report.status)
|
|
169
|
-
console.log('Output: ' + report.out)
|
|
170
|
-
console.log('Files: ' + report.fileCount)
|
|
171
|
-
if (report.missing.length) console.log('Missing: ' + report.missing.join(', '))
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (report.status === 'failed' || report.status === 'exists') process.exit(1)
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import crypto from 'node:crypto'
|
|
5
|
+
|
|
6
|
+
const args = process.argv.slice(2)
|
|
7
|
+
|
|
8
|
+
function readArg(name, fallback = null) {
|
|
9
|
+
const index = args.indexOf(name)
|
|
10
|
+
if (index === -1) return fallback
|
|
11
|
+
return args[index + 1] ?? fallback
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
|
|
15
|
+
const label = readArg('--label', 'gse-local-' + new Date().toISOString().slice(0, 10))
|
|
16
|
+
const out = path.resolve(readArg('--out', path.join(process.env.TEMP || process.env.TMP || root, label)))
|
|
17
|
+
const force = args.includes('--force')
|
|
18
|
+
const dryRun = args.includes('--dry-run')
|
|
19
|
+
const jsonOnly = args.includes('--json')
|
|
20
|
+
|
|
21
|
+
const include = [
|
|
22
|
+
'package.json',
|
|
23
|
+
'SKILL.md',
|
|
24
|
+
'README.md',
|
|
25
|
+
'README.zh-CN.md',
|
|
26
|
+
'CHANGELOG.md',
|
|
27
|
+
'CONTRIBUTING.md',
|
|
28
|
+
'LICENSE',
|
|
29
|
+
'SECURITY.md',
|
|
30
|
+
'SUPPORT.md',
|
|
31
|
+
'.github',
|
|
32
|
+
'agents',
|
|
33
|
+
'assets',
|
|
34
|
+
'examples',
|
|
35
|
+
'references',
|
|
36
|
+
'scripts',
|
|
37
|
+
'.gse',
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
const excludeNames = new Set(['.git', 'node_modules', 'dist', '.DS_Store'])
|
|
41
|
+
const packageGseAllowlist = new Set([
|
|
42
|
+
'.gse/README.md',
|
|
43
|
+
'.gse/project-profile.md',
|
|
44
|
+
'.gse/quality-gates.md',
|
|
45
|
+
'.gse/gse-development-protocol.md',
|
|
46
|
+
'.gse/state.json',
|
|
47
|
+
'.gse/releases',
|
|
48
|
+
'.gse/releases/public-release-owner-required.md',
|
|
49
|
+
'.gse/releases/public-security-contact-owner-required.md',
|
|
50
|
+
])
|
|
51
|
+
const excludeRelativePrefixes = [
|
|
52
|
+
'.gse/evidence/',
|
|
53
|
+
'.gse/benchmark-audits/',
|
|
54
|
+
'.gse/acceptance/',
|
|
55
|
+
'.gse/archive/',
|
|
56
|
+
'.gse/changes/',
|
|
57
|
+
'.gse/release-bundles/',
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
function exists(relativePath) {
|
|
61
|
+
return fs.existsSync(path.join(root, relativePath))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function shouldExclude(relativePath) {
|
|
65
|
+
const normalized = relativePath.replace(/\\/g, '/')
|
|
66
|
+
if (normalized.startsWith('.gse/') && !packageGseAllowlist.has(normalized)) return true
|
|
67
|
+
if (excludeRelativePrefixes.some((prefix) => normalized.startsWith(prefix))) return true
|
|
68
|
+
return normalized.split('/').some((part) => excludeNames.has(part))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function walk(sourcePath, basePath = sourcePath) {
|
|
72
|
+
const entries = []
|
|
73
|
+
if (!fs.existsSync(sourcePath)) return entries
|
|
74
|
+
const stat = fs.statSync(sourcePath)
|
|
75
|
+
if (stat.isFile()) {
|
|
76
|
+
const relativePath = path.relative(root, sourcePath).replace(/\\/g, '/')
|
|
77
|
+
if (!shouldExclude(relativePath)) entries.push({ sourcePath, relativePath, bytes: stat.size })
|
|
78
|
+
return entries
|
|
79
|
+
}
|
|
80
|
+
for (const child of fs.readdirSync(sourcePath, { withFileTypes: true })) {
|
|
81
|
+
const fullPath = path.join(sourcePath, child.name)
|
|
82
|
+
const relativePath = path.relative(root, fullPath).replace(/\\/g, '/')
|
|
83
|
+
if (shouldExclude(relativePath)) continue
|
|
84
|
+
if (child.isDirectory()) entries.push(...walk(fullPath, basePath))
|
|
85
|
+
else if (child.isFile()) entries.push({ sourcePath: fullPath, relativePath, bytes: fs.statSync(fullPath).size })
|
|
86
|
+
}
|
|
87
|
+
return entries
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function copyFile(entry) {
|
|
91
|
+
const targetPath = path.join(out, entry.relativePath)
|
|
92
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true })
|
|
93
|
+
fs.copyFileSync(entry.sourcePath, targetPath)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function sha256(filePath) {
|
|
97
|
+
return crypto.createHash('sha256').update(fs.readFileSync(filePath)).digest('hex')
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const missing = include.filter((item) => !exists(item))
|
|
101
|
+
const files = include.flatMap((item) => walk(path.join(root, item)))
|
|
102
|
+
const sortedFiles = files.map((item) => item.relativePath).sort()
|
|
103
|
+
const fileHashes = Object.fromEntries(
|
|
104
|
+
sortedFiles.map((relativePath) => [relativePath, sha256(path.join(root, relativePath))]),
|
|
105
|
+
)
|
|
106
|
+
const manifest = {
|
|
107
|
+
schemaVersion: 1,
|
|
108
|
+
packageName: 'gse',
|
|
109
|
+
label,
|
|
110
|
+
generatedAt: new Date().toISOString(),
|
|
111
|
+
fileCount: files.length,
|
|
112
|
+
totalBytes: files.reduce((sum, item) => sum + item.bytes, 0),
|
|
113
|
+
includes: include,
|
|
114
|
+
excludes: [...excludeNames, ...excludeRelativePrefixes, '.gse/* except portable package allowlist'],
|
|
115
|
+
packageGseAllowlist: [...packageGseAllowlist].sort(),
|
|
116
|
+
entrypoints: {
|
|
117
|
+
nodePackage: 'package.json',
|
|
118
|
+
skill: 'SKILL.md',
|
|
119
|
+
cli: 'scripts/gse.mjs',
|
|
120
|
+
validate: 'scripts/validate-gse.mjs',
|
|
121
|
+
npmPackageAudit: 'scripts/audit-npm-package-metadata.mjs',
|
|
122
|
+
validationProfile: 'scripts/run-validation-profile.mjs',
|
|
123
|
+
install: 'scripts/install-gse.mjs',
|
|
124
|
+
commands: 'references/commands.md',
|
|
125
|
+
},
|
|
126
|
+
integrity: {
|
|
127
|
+
algorithm: 'sha256',
|
|
128
|
+
},
|
|
129
|
+
files: sortedFiles,
|
|
130
|
+
fileHashes,
|
|
131
|
+
}
|
|
132
|
+
manifest.integrity.packageDigest = crypto
|
|
133
|
+
.createHash('sha256')
|
|
134
|
+
.update(JSON.stringify({ files: manifest.files, fileHashes: manifest.fileHashes }))
|
|
135
|
+
.digest('hex')
|
|
136
|
+
|
|
137
|
+
const report = {
|
|
138
|
+
root,
|
|
139
|
+
out,
|
|
140
|
+
label,
|
|
141
|
+
dryRun,
|
|
142
|
+
status: missing.length === 0 ? 'ready' : 'failed',
|
|
143
|
+
missing,
|
|
144
|
+
fileCount: files.length,
|
|
145
|
+
totalBytes: manifest.totalBytes,
|
|
146
|
+
manifestPath: path.join(out, 'gse-package-manifest.json'),
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (missing.length === 0 && !dryRun) {
|
|
150
|
+
if (fs.existsSync(out)) {
|
|
151
|
+
if (!force) {
|
|
152
|
+
report.status = 'exists'
|
|
153
|
+
report.recommendation = 'Use --force or choose another --out directory.'
|
|
154
|
+
} else {
|
|
155
|
+
fs.rmSync(out, { recursive: true, force: true })
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (report.status === 'ready') {
|
|
159
|
+
fs.mkdirSync(out, { recursive: true })
|
|
160
|
+
for (const file of files) copyFile(file)
|
|
161
|
+
fs.writeFileSync(path.join(out, 'gse-package-manifest.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf8')
|
|
162
|
+
report.status = 'written'
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
167
|
+
else {
|
|
168
|
+
console.log('GSE package status: ' + report.status)
|
|
169
|
+
console.log('Output: ' + report.out)
|
|
170
|
+
console.log('Files: ' + report.fileCount)
|
|
171
|
+
if (report.missing.length) console.log('Missing: ' + report.missing.join(', '))
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (report.status === 'failed' || report.status === 'exists') process.exit(1)
|