@supersuit/hypercontext 0.0.0-stage → 0.1.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/src/stamp.mjs ADDED
@@ -0,0 +1,75 @@
1
+ // The backfill: give every existing record the `standard:` it is missing.
2
+ //
3
+ // A kind with a package is stamped BY ITS PACKAGE, through the command that package ships for
4
+ // it, because the package knows its own key order and every other thing its writers keep; this
5
+ // file only calls it. A kind with no package is stamped here, by the one byte-preserving edit in
6
+ // selfdoc.mjs. A kind marked `stampable: false` is never touched, and the report says why.
7
+ //
8
+ // Dry run unless `apply`. Never commits.
9
+ import { readFileSync, writeFileSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { spawnSync } from 'node:child_process';
12
+ import { KINDS, bareStandard } from './kinds.mjs';
13
+ import { findRecords, superprojectRoots, documentHomes, fsDefault } from './find.mjs';
14
+ import { judge, acceptedFor, standardOf, stampStandard } from './selfdoc.mjs';
15
+ import { resolvePackage, packageVersion } from './packages.mjs';
16
+
17
+ const STANDARDS = Object.fromEntries(KINDS.map((k) => [k.kind, k.standard]));
18
+
19
+ // Each package's own backfill command, as its README documents it. `apply` adds the write flag.
20
+ export const PACKAGE_STAMPS = {
21
+ self: (ws, apply) => [['stamp-standard', '--workspace', ws, ...(apply ? ['--write'] : [])]],
22
+ friend: (ws, apply) => [['stamp', '--people', join(ws, 'people'), ...(apply ? ['--apply'] : [])]],
23
+ group: (ws, apply) => [['migrate', join(ws, 'people/groups'), ...(apply ? ['--apply'] : [])]],
24
+ // transcript-md takes its mutation lock and checks each file's hash before it writes.
25
+ piece: (ws, apply, { homes }) => homes.map((h) => ['stamp', join(ws, h), ...(apply ? ['--apply'] : [])]),
26
+ conversation: (ws, apply) => [['stamp-standard', '--workspace', ws, ...(apply ? ['--apply'] : [])]],
27
+ superproject: (ws, apply, { roots }) => roots.map((r) => ['migrate', '--root', join(ws, r), '--stamp-standard', ...(apply ? ['--apply'] : [])]),
28
+ };
29
+
30
+ /**
31
+ * @returns {Promise<{apply: boolean, kinds: Array<{kind, missing, via, changed?, skipped?, note?}>}>}
32
+ */
33
+ export async function stamp(workspace, { kinds, apply = false, packagesDir, fs = fsDefault } = {}) {
34
+ const out = [];
35
+ const roots = superprojectRoots(workspace, fs);
36
+ const done = new Set();
37
+ for (const k of KINDS.filter((x) => !kinds || kinds.includes(x.kind))) {
38
+ const records = findRecords(workspace, k.kind, fs);
39
+ const missing = records.filter((rel) => {
40
+ const text = readFileSync(join(workspace, rel), 'utf8');
41
+ return !judge(text, k, { alsoAccept: acceptedFor(k.kind, standardOf(text, k.format).data, STANDARDS) }).selfDocumenting;
42
+ });
43
+ const row = { kind: k.kind, records: records.length, missing: missing.length };
44
+ if (!missing.length) { out.push({ ...row, via: 'nothing to do' }); continue; }
45
+ if (k.stampable === false) { out.push({ ...row, via: 'not stamped', note: k.why }); continue; }
46
+
47
+ const lead = k.sharesLint ?? k.kind;
48
+ if (k.pkg && PACKAGE_STAMPS[lead]) {
49
+ if (done.has(lead)) { out.push({ ...row, via: `${k.pkg.name}, with ${lead}` }); continue; }
50
+ done.add(lead);
51
+ const dir = resolvePackage(k.pkg, { packagesDir });
52
+ if (!dir) { out.push({ ...row, via: 'not stamped', note: `${k.pkg.name} is not installed` }); continue; }
53
+ const runs = PACKAGE_STAMPS[lead](workspace, apply, { roots, homes: documentHomes(workspace, fs) }).map((args) => {
54
+ const r = spawnSync(process.execPath, [join(dir, k.pkg.bin), ...args], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
55
+ return { args: args.join(' '), status: r.status, stderr: (r.stderr ?? '').trim().split('\n')[0] ?? '' };
56
+ });
57
+ // Exit 2 is a usage error in every one of these packages: the command this file names is
58
+ // not one that version knows, which is a version mismatch, never a record problem.
59
+ const failed = runs.filter((r) => r.status === 2 || r.status === null);
60
+ out.push({ ...row, via: `${k.pkg.name}@${packageVersion(dir)}`, ...(failed.length ? { note: `did not run: ${failed.map((f) => `${f.args} (${f.stderr})`).join('; ')}` } : {}) });
61
+ continue;
62
+ }
63
+ if (k.pkg) { out.push({ ...row, via: 'not stamped', note: `${k.pkg.name} ships no stamp this package knows how to call` }); continue; }
64
+
65
+ let changed = 0; const reasons = {};
66
+ for (const rel of missing) {
67
+ const p = join(workspace, rel);
68
+ const r = stampStandard(readFileSync(p, 'utf8'), k.standard, bareStandard(k.kind));
69
+ if (r.changed) { changed++; if (apply) writeFileSync(p, r.text); }
70
+ else reasons[r.reason] = (reasons[r.reason] ?? 0) + 1;
71
+ }
72
+ out.push({ ...row, via: '@supersuit/hypercontext', changed, skipped: missing.length - changed, ...(Object.keys(reasons).length ? { reasons } : {}) });
73
+ }
74
+ return { apply, kinds: out };
75
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "standard": "https://hypercontext.wiki/standards/checkpoint/v1",
4
+ "kind": "checkpoint",
5
+ "version": 1,
6
+ "title": "A session checkpoint",
7
+ "status": "current",
8
+ "superseded_by": null,
9
+ "latest": "https://hypercontext.wiki/standards/checkpoint",
10
+ "record": {
11
+ "path": "checkpoints/YYYY-MM-DD-HHMMSS-<slug>.md",
12
+ "format": "md"
13
+ },
14
+ "header": {
15
+ "required": [
16
+ "standard",
17
+ "kind",
18
+ "summary"
19
+ ],
20
+ "keys": {
21
+ "standard": {
22
+ "const": "https://hypercontext.wiki/standards/checkpoint/v1"
23
+ },
24
+ "kind": {
25
+ "const": "checkpoint"
26
+ },
27
+ "summary": {
28
+ "type": "string"
29
+ },
30
+ "date": {
31
+ "type": "string"
32
+ },
33
+ "sha": {
34
+ "type": "string"
35
+ }
36
+ }
37
+ },
38
+ "validator": null,
39
+ "checked_by": {
40
+ "package": "@supersuit/hypercontext",
41
+ "implements_since": "0.1.0",
42
+ "check": "npx -y @supersuit/hypercontext@^0.1.0 check . --kind checkpoint --json",
43
+ "backfill": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind checkpoint --apply",
44
+ "note": "No package checks this shape yet; only the shared property (the record names this standard) is checked."
45
+ },
46
+ "codes": [
47
+ {
48
+ "code": "self-doc:missing",
49
+ "level": "error",
50
+ "means": "the record names no standard, the unversioned URL written before versions, or another kind's standard",
51
+ "fix": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind checkpoint --apply"
52
+ },
53
+ {
54
+ "code": "self-doc:version",
55
+ "level": "error",
56
+ "means": "the record names a version of this standard that the checker here does not implement",
57
+ "fix": "upgrade @supersuit/hypercontext, or rewrite the record to a version it implements"
58
+ }
59
+ ],
60
+ "umbrella": "npx -y @supersuit/hypercontext check <workspace>"
61
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "standard": "https://hypercontext.wiki/standards/document/v1",
4
+ "kind": "document",
5
+ "version": 1,
6
+ "title": "A document",
7
+ "status": "current",
8
+ "superseded_by": null,
9
+ "latest": "https://hypercontext.wiki/standards/document",
10
+ "record": {
11
+ "path": "documents/YYYY-MM-DD-HHMMSS-<slug>.md, or <superproject>/documents/",
12
+ "format": "md"
13
+ },
14
+ "header": {
15
+ "required": [
16
+ "standard",
17
+ "audience"
18
+ ],
19
+ "keys": {
20
+ "standard": {
21
+ "const": "https://hypercontext.wiki/standards/document/v1"
22
+ },
23
+ "kind": {
24
+ "enum": [
25
+ "brief",
26
+ "spec",
27
+ "design",
28
+ "plan",
29
+ "decision",
30
+ "draft",
31
+ "analysis",
32
+ "transcript",
33
+ "other"
34
+ ]
35
+ },
36
+ "status": {
37
+ "enum": [
38
+ "draft",
39
+ "active",
40
+ "approved",
41
+ "final",
42
+ "shipped",
43
+ "superseded"
44
+ ]
45
+ },
46
+ "audience": {
47
+ "type": "string"
48
+ },
49
+ "created": {
50
+ "type": "string",
51
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}"
52
+ }
53
+ }
54
+ },
55
+ "validator": null,
56
+ "checked_by": {
57
+ "package": "@supersuit/hypercontext",
58
+ "implements_since": "0.1.0",
59
+ "check": "npx -y @supersuit/hypercontext@^0.1.0 check . --kind document --json",
60
+ "backfill": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind document --apply",
61
+ "note": "No package checks this shape yet; only the shared property (the record names this standard) is checked."
62
+ },
63
+ "codes": [
64
+ {
65
+ "code": "self-doc:missing",
66
+ "level": "error",
67
+ "means": "the record names no standard, the unversioned URL written before versions, or another kind's standard",
68
+ "fix": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind document --apply"
69
+ },
70
+ {
71
+ "code": "self-doc:version",
72
+ "level": "error",
73
+ "means": "the record names a version of this standard that the checker here does not implement",
74
+ "fix": "upgrade @supersuit/hypercontext, or rewrite the record to a version it implements"
75
+ }
76
+ ],
77
+ "umbrella": "npx -y @supersuit/hypercontext check <workspace>"
78
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "standard": "https://hypercontext.wiki/standards/hdsop/v1",
4
+ "kind": "hdsop",
5
+ "version": 1,
6
+ "title": "A workflow map (HDSOP)",
7
+ "status": "current",
8
+ "superseded_by": null,
9
+ "latest": "https://hypercontext.wiki/standards/hdsop",
10
+ "record": {
11
+ "path": "workflows/<slug>.md",
12
+ "format": "md"
13
+ },
14
+ "header": {
15
+ "required": [
16
+ "standard",
17
+ "title",
18
+ "id"
19
+ ],
20
+ "keys": {
21
+ "standard": {
22
+ "const": "https://hypercontext.wiki/standards/hdsop/v1"
23
+ },
24
+ "title": {
25
+ "type": "string"
26
+ },
27
+ "id": {
28
+ "type": "string"
29
+ },
30
+ "frequency": {
31
+ "type": "string"
32
+ },
33
+ "owner": {
34
+ "type": "string"
35
+ }
36
+ }
37
+ },
38
+ "validator": null,
39
+ "checked_by": {
40
+ "package": "@supersuit/hypercontext",
41
+ "implements_since": "0.1.0",
42
+ "check": "npx -y @supersuit/hypercontext@^0.1.0 check . --kind hdsop --json",
43
+ "backfill": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind hdsop --apply",
44
+ "note": "No package checks this shape yet; only the shared property (the record names this standard) is checked."
45
+ },
46
+ "codes": [
47
+ {
48
+ "code": "self-doc:missing",
49
+ "level": "error",
50
+ "means": "the record names no standard, the unversioned URL written before versions, or another kind's standard",
51
+ "fix": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind hdsop --apply"
52
+ },
53
+ {
54
+ "code": "self-doc:version",
55
+ "level": "error",
56
+ "means": "the record names a version of this standard that the checker here does not implement",
57
+ "fix": "upgrade @supersuit/hypercontext, or rewrite the record to a version it implements"
58
+ }
59
+ ],
60
+ "umbrella": "npx -y @supersuit/hypercontext check <workspace>"
61
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "standard": "https://hypercontext.wiki/standards/recurrent/v1",
4
+ "kind": "recurrent",
5
+ "version": 1,
6
+ "title": "A recurrent",
7
+ "status": "current",
8
+ "superseded_by": null,
9
+ "latest": "https://hypercontext.wiki/standards/recurrent",
10
+ "record": {
11
+ "path": "recurrents/<slug>.md",
12
+ "format": "md"
13
+ },
14
+ "header": {
15
+ "required": [
16
+ "standard"
17
+ ],
18
+ "keys": {
19
+ "standard": {
20
+ "const": "https://hypercontext.wiki/standards/recurrent/v1"
21
+ }
22
+ }
23
+ },
24
+ "validator": null,
25
+ "checked_by": {
26
+ "package": "@supersuit/hypercontext",
27
+ "implements_since": "0.1.0",
28
+ "check": "npx -y @supersuit/hypercontext@^0.1.0 check . --kind recurrent --json",
29
+ "backfill": null,
30
+ "note": "A recurrent keeps its fields as bold labels in its body today; its writer converts it to a header before it can carry the standard, so no backfill runs."
31
+ },
32
+ "codes": [
33
+ {
34
+ "code": "self-doc:missing",
35
+ "level": "error",
36
+ "means": "the record names no standard, the unversioned URL written before versions, or another kind's standard",
37
+ "fix": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind recurrent --apply"
38
+ },
39
+ {
40
+ "code": "self-doc:version",
41
+ "level": "error",
42
+ "means": "the record names a version of this standard that the checker here does not implement",
43
+ "fix": "upgrade @supersuit/hypercontext, or rewrite the record to a version it implements"
44
+ }
45
+ ],
46
+ "umbrella": "npx -y @supersuit/hypercontext check <workspace>"
47
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "standard": "https://hypercontext.wiki/standards/tile-app/v1",
4
+ "kind": "tile-app",
5
+ "version": 1,
6
+ "title": "A tile app",
7
+ "status": "current",
8
+ "superseded_by": null,
9
+ "latest": "https://hypercontext.wiki/standards/tile-app",
10
+ "record": {
11
+ "path": "helm/tile-apps/<id>/app.json",
12
+ "format": "json"
13
+ },
14
+ "header": {
15
+ "required": [
16
+ "standard",
17
+ "id",
18
+ "title"
19
+ ],
20
+ "keys": {
21
+ "standard": {
22
+ "const": "https://hypercontext.wiki/standards/tile-app/v1"
23
+ },
24
+ "id": {
25
+ "type": "string"
26
+ },
27
+ "title": {
28
+ "type": "string"
29
+ },
30
+ "summary": {
31
+ "type": "string"
32
+ }
33
+ }
34
+ },
35
+ "validator": null,
36
+ "checked_by": {
37
+ "package": "@supersuit/hypercontext",
38
+ "implements_since": "0.1.0",
39
+ "check": "npx -y @supersuit/hypercontext@^0.1.0 check . --kind tile-app --json",
40
+ "backfill": null,
41
+ "note": "The Helm host reads app.json; the key is added once the host accepts it, so no backfill runs."
42
+ },
43
+ "codes": [
44
+ {
45
+ "code": "self-doc:missing",
46
+ "level": "error",
47
+ "means": "the record names no standard, the unversioned URL written before versions, or another kind's standard",
48
+ "fix": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind tile-app --apply"
49
+ },
50
+ {
51
+ "code": "self-doc:version",
52
+ "level": "error",
53
+ "means": "the record names a version of this standard that the checker here does not implement",
54
+ "fix": "upgrade @supersuit/hypercontext, or rewrite the record to a version it implements"
55
+ }
56
+ ],
57
+ "umbrella": "npx -y @supersuit/hypercontext check <workspace>"
58
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "standard": "https://hypercontext.wiki/standards/workflow-catalog/v1",
4
+ "kind": "workflow-catalog",
5
+ "version": 1,
6
+ "title": "The workflow catalog",
7
+ "status": "current",
8
+ "superseded_by": null,
9
+ "latest": "https://hypercontext.wiki/standards/workflow-catalog",
10
+ "record": {
11
+ "path": "workflows/CATALOG.md",
12
+ "format": "md"
13
+ },
14
+ "header": {
15
+ "required": [
16
+ "standard"
17
+ ],
18
+ "keys": {
19
+ "standard": {
20
+ "const": "https://hypercontext.wiki/standards/workflow-catalog/v1"
21
+ }
22
+ }
23
+ },
24
+ "validator": null,
25
+ "checked_by": {
26
+ "package": "@supersuit/hypercontext",
27
+ "implements_since": "0.1.0",
28
+ "check": "npx -y @supersuit/hypercontext@^0.1.0 check . --kind workflow-catalog --json",
29
+ "backfill": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind workflow-catalog --apply",
30
+ "note": "No package checks this shape yet; only the shared property (the record names this standard) is checked."
31
+ },
32
+ "codes": [
33
+ {
34
+ "code": "self-doc:missing",
35
+ "level": "error",
36
+ "means": "the record names no standard, the unversioned URL written before versions, or another kind's standard",
37
+ "fix": "npx -y @supersuit/hypercontext@^0.1.0 stamp . --kind workflow-catalog --apply"
38
+ },
39
+ {
40
+ "code": "self-doc:version",
41
+ "level": "error",
42
+ "means": "the record names a version of this standard that the checker here does not implement",
43
+ "fix": "upgrade @supersuit/hypercontext, or rewrite the record to a version it implements"
44
+ }
45
+ ],
46
+ "umbrella": "npx -y @supersuit/hypercontext check <workspace>"
47
+ }