@heychunky/core 0.12.0 → 0.13.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.
@@ -14,6 +14,7 @@ export * from "./provision.ts";
14
14
  export * from "./decommission.ts";
15
15
  export * from "./migrations.ts";
16
16
  export * from "./promote.ts";
17
+ export * from "./runs.ts";
17
18
  export * from "./entrypoints.ts";
18
19
  export * from "./chunks.ts";
19
20
  export * from "./services/github.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAG5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAG5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -14,6 +14,7 @@ export * from "./provision.js";
14
14
  export * from "./decommission.js";
15
15
  export * from "./migrations.js";
16
16
  export * from "./promote.js";
17
+ export * from "./runs.js";
17
18
  export * from "./entrypoints.js";
18
19
  export * from "./chunks.js";
19
20
  // One file per service, matching the registry.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAE5B,+CAA+C;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAE5B,+CAA+C;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * What the factory did, and on whose behalf.
3
+ *
4
+ * Provisioning has always returned a `Run` and never cared where it went; the
5
+ * CLI writes one to `~/.heychunky/runs` and says in its own header that the
6
+ * shape was settled and a table would take it eventually. This is that table.
7
+ *
8
+ * It matters more now than it did, because a superagent works unattended. A
9
+ * provisioning run had a person watching it who could say what happened; a run
10
+ * that classified, planned, implemented and reviewed while nobody was looking
11
+ * leaves nothing behind but comments on an issue and a log that ages out. The
12
+ * question "what has chunky been doing, and what did it cost" has had no answer
13
+ * anywhere.
14
+ *
15
+ * Two things are deliberately separate here:
16
+ *
17
+ * who may *start* a run on a target — `appFor` for an app, role for the
18
+ * factory's own repositories
19
+ * who may *see* a run afterwards — the operator who asked, and superadmin
20
+ *
21
+ * The second is what this file answers, and it keys on the operator rather than
22
+ * on the app precisely so a decommissioned app does not take its history with
23
+ * it.
24
+ */
25
+ import type { Register } from "./master.ts";
26
+ import type { StepResult } from "./provision.ts";
27
+ import type { User } from "./users.ts";
28
+ /** Where the work came from: `github:heychunkydev/x#12`, `email`, `cli`. */
29
+ export type RunSource = string;
30
+ export interface FactoryRun {
31
+ id: string;
32
+ /** Always known. `heychunkydev/heychunky-core`. */
33
+ repo: string;
34
+ /**
35
+ * The app this repository belongs to, when it is one.
36
+ *
37
+ * Null means no app row — either a factory repository, which is machinery
38
+ * rather than somebody's app, or an app that has since been taken down. Both
39
+ * are read the same way on purpose: neither has an owner to answer to, so
40
+ * neither is a developer's to see.
41
+ */
42
+ app_id: string | null;
43
+ /** Whose behalf it ran on. Never chunky's own: every run traces to a human. */
44
+ operator_id: string;
45
+ source: RunSource;
46
+ title: string | null;
47
+ /** The same shape provisioning reports, so one renderer serves both. */
48
+ steps: StepResult[];
49
+ /** What the models cost, when the caller knows. */
50
+ cost: string | null;
51
+ outcome: "running" | "done" | "failed";
52
+ created_at: string;
53
+ finished_at: string | null;
54
+ }
55
+ /** What a caller supplies. The id is theirs to choose, so a run can be updated. */
56
+ export interface RunRecord {
57
+ id: string;
58
+ repo: string;
59
+ appId?: string | null;
60
+ operatorId: string;
61
+ source: RunSource;
62
+ title?: string | null;
63
+ steps: StepResult[];
64
+ cost?: string | null;
65
+ outcome: FactoryRun["outcome"];
66
+ finishedAt?: string | null;
67
+ }
68
+ /**
69
+ * Make sure the table is there.
70
+ *
71
+ * `create table if not exists`, called before a write, which is the same way
72
+ * the migration ledger arrives in an app's database. The register has no
73
+ * migration mechanism of its own — `apps` and `users` were made by hand — and
74
+ * inventing one to add a single table would be a larger decision than this
75
+ * file is entitled to make. This at least leaves the schema written down in
76
+ * the repository rather than only in the database.
77
+ */
78
+ export declare function ensureRuns(register: Register): Promise<void>;
79
+ /**
80
+ * Write a run, or bring an existing one up to date.
81
+ *
82
+ * One call rather than start/step/finish, because a station boundary is the
83
+ * only moment worth recording and the caller already holds the whole list by
84
+ * then. Upserting on the id also means a run interrupted halfway leaves the
85
+ * steps it did reach rather than nothing at all — the same property the
86
+ * migration ledger has, and for the same reason.
87
+ */
88
+ export declare function recordRun(run: RunRecord, register: Register): Promise<void>;
89
+ /**
90
+ * The runs a person may see, newest first.
91
+ *
92
+ * Scoped on who asked rather than on which app, so a developer keeps the
93
+ * history of work they requested even after the app it touched is gone, and so
94
+ * runs against the factory's own repositories — which have no app and no owner
95
+ * — are visible to the superadmin who started them and to nobody else.
96
+ */
97
+ export declare function listRuns(user: Pick<User, "id" | "role">, register: Register, limit?: number): Promise<FactoryRun[]>;
98
+ //# sourceMappingURL=runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/admin/runs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,wEAAwE;IACxE,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,mDAAmD;IACnD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjF;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,EAC/B,QAAQ,EAAE,QAAQ,EAClB,KAAK,SAAK,GACT,OAAO,CAAC,UAAU,EAAE,CAAC,CAQvB"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Make sure the table is there.
3
+ *
4
+ * `create table if not exists`, called before a write, which is the same way
5
+ * the migration ledger arrives in an app's database. The register has no
6
+ * migration mechanism of its own — `apps` and `users` were made by hand — and
7
+ * inventing one to add a single table would be a larger decision than this
8
+ * file is entitled to make. This at least leaves the schema written down in
9
+ * the repository rather than only in the database.
10
+ */
11
+ export async function ensureRuns(register) {
12
+ await register.write(`create table if not exists runs (
13
+ id uuid primary key,
14
+ repo text not null,
15
+ app_id uuid references apps(id) on delete set null,
16
+ operator_id uuid not null references users(id),
17
+ source text not null,
18
+ title text,
19
+ steps jsonb not null default '[]'::jsonb,
20
+ cost numeric,
21
+ outcome text not null default 'running',
22
+ created_at timestamptz not null default now(),
23
+ finished_at timestamptz
24
+ )`);
25
+ }
26
+ /**
27
+ * Write a run, or bring an existing one up to date.
28
+ *
29
+ * One call rather than start/step/finish, because a station boundary is the
30
+ * only moment worth recording and the caller already holds the whole list by
31
+ * then. Upserting on the id also means a run interrupted halfway leaves the
32
+ * steps it did reach rather than nothing at all — the same property the
33
+ * migration ledger has, and for the same reason.
34
+ */
35
+ export async function recordRun(run, register) {
36
+ await ensureRuns(register);
37
+ await register.write(`insert into runs (id, repo, app_id, operator_id, source, title, steps, cost, outcome, finished_at)
38
+ values ($1, $2, $3, $4, $5, $6, $7::jsonb, $8, $9, $10)
39
+ on conflict (id) do update set
40
+ steps = excluded.steps,
41
+ cost = coalesce(excluded.cost, runs.cost),
42
+ outcome = excluded.outcome,
43
+ title = coalesce(excluded.title, runs.title),
44
+ finished_at = coalesce(excluded.finished_at, runs.finished_at)`, [
45
+ run.id, run.repo, run.appId ?? null, run.operatorId, run.source,
46
+ run.title ?? null, JSON.stringify(run.steps), run.cost ?? null,
47
+ run.outcome, run.finishedAt ?? null,
48
+ ]);
49
+ }
50
+ /**
51
+ * The runs a person may see, newest first.
52
+ *
53
+ * Scoped on who asked rather than on which app, so a developer keeps the
54
+ * history of work they requested even after the app it touched is gone, and so
55
+ * runs against the factory's own repositories — which have no app and no owner
56
+ * — are visible to the superadmin who started them and to nobody else.
57
+ */
58
+ export async function listRuns(user, register, limit = 50) {
59
+ await ensureRuns(register);
60
+ const select = `select * from runs`;
61
+ const { rows } = user.role === "superadmin"
62
+ ? await register.query(`${select} order by created_at desc limit $1`, [limit])
63
+ : await register.query(`${select} where operator_id = $1 order by created_at desc limit $2`, [user.id, limit]);
64
+ return rows;
65
+ }
66
+ //# sourceMappingURL=runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/admin/runs.ts"],"names":[],"mappings":"AAuEA;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAkB;IACjD,MAAM,QAAQ,CAAC,KAAK,CAClB;;;;;;;;;;;;OAYG,CACJ,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAc,EAAE,QAAkB;IAChE,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,QAAQ,CAAC,KAAK,CAClB;;;;;;;sEAOkE,EAClE;QACE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM;QAC/D,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QAC9D,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,IAAI,IAAI;KACpC,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAA+B,EAC/B,QAAkB,EAClB,KAAK,GAAG,EAAE;IAEV,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,oBAAoB,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,KAAK,YAAY;QACzC,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,MAAM,oCAAoC,EAAE,CAAC,KAAK,CAAC,CAAC;QAC9E,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,CAClB,GAAG,MAAM,2DAA2D,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9F,OAAO,IAA+B,CAAC;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heychunky/core",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "The engine the Chunky CLI, worker and apps run on.",
5
5
  "license": "MIT",
6
6
  "type": "module",