@inharness-ai/claude4spec 1.0.6 → 1.0.8

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.
Files changed (103) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/client/assets/{arc-CqFoQdai.js → arc-Ri_rE3A4.js} +1 -1
  3. package/dist/client/assets/{architectureDiagram-3BPJPVTR-CIEQ1CV_.js → architectureDiagram-3BPJPVTR-C7KU6Gxy.js} +1 -1
  4. package/dist/client/assets/{blockDiagram-GPEHLZMM-DwCCDYZs.js → blockDiagram-GPEHLZMM-XP57kEB6.js} +1 -1
  5. package/dist/client/assets/{c4Diagram-AAUBKEIU-DB988zZs.js → c4Diagram-AAUBKEIU-vQE6EvG4.js} +1 -1
  6. package/dist/client/assets/channel-CXaSz-yc.js +1 -0
  7. package/dist/client/assets/{chunk-2J33WTMH-Bwc9B4Id.js → chunk-2J33WTMH-CDaw1-z0.js} +1 -1
  8. package/dist/client/assets/{chunk-4BX2VUAB-ClOw-zt3.js → chunk-4BX2VUAB-CdUEf5WH.js} +1 -1
  9. package/dist/client/assets/{chunk-55IACEB6-B513D_Oz.js → chunk-55IACEB6-CJjUfYKD.js} +1 -1
  10. package/dist/client/assets/{chunk-727SXJPM-CvT-ppRD.js → chunk-727SXJPM-DkgytNym.js} +1 -1
  11. package/dist/client/assets/{chunk-AQP2D5EJ-BDZ-uKjF.js → chunk-AQP2D5EJ-B23_HIH8.js} +1 -1
  12. package/dist/client/assets/{chunk-FMBD7UC4-DlnsCvyP.js → chunk-FMBD7UC4-BOxU6c6d.js} +1 -1
  13. package/dist/client/assets/{chunk-ND2GUHAM-Cv4kIfqi.js → chunk-ND2GUHAM-DM3Qjus5.js} +1 -1
  14. package/dist/client/assets/{chunk-QZHKN3VN-Boyq-O-A.js → chunk-QZHKN3VN-CapbZIUP.js} +1 -1
  15. package/dist/client/assets/classDiagram-4FO5ZUOK-CiPHXsyE.js +1 -0
  16. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CiPHXsyE.js +1 -0
  17. package/dist/client/assets/{cose-bilkent-S5V4N54A-B4fXXqZV.js → cose-bilkent-S5V4N54A-CTNIJ0dY.js} +1 -1
  18. package/dist/client/assets/{dagre-BM42HDAG-D7JvdAaj.js → dagre-BM42HDAG-BRrO0WSt.js} +1 -1
  19. package/dist/client/assets/{diagram-2AECGRRQ-TqVC9_06.js → diagram-2AECGRRQ-CMCgz46p.js} +1 -1
  20. package/dist/client/assets/{diagram-5GNKFQAL-BJE7Sfvp.js → diagram-5GNKFQAL-Be67M_wK.js} +1 -1
  21. package/dist/client/assets/{diagram-KO2AKTUF-dDI3Q4Xy.js → diagram-KO2AKTUF-C1lam27A.js} +1 -1
  22. package/dist/client/assets/{diagram-LMA3HP47-zrNXdbAH.js → diagram-LMA3HP47-3u3xFJ_q.js} +1 -1
  23. package/dist/client/assets/{diagram-OG6HWLK6-C9RoGREB.js → diagram-OG6HWLK6-DIVEfPgU.js} +1 -1
  24. package/dist/client/assets/{erDiagram-TEJ5UH35-BIOg0Mgx.js → erDiagram-TEJ5UH35-CoXGGm8G.js} +1 -1
  25. package/dist/client/assets/{flowDiagram-I6XJVG4X-C5olRPEY.js → flowDiagram-I6XJVG4X-CZ5BV_Ix.js} +1 -1
  26. package/dist/client/assets/{ganttDiagram-6RSMTGT7-Daqt3_2M.js → ganttDiagram-6RSMTGT7-BvPLC5Cv.js} +1 -1
  27. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-E09LH7cR.js → gitGraphDiagram-PVQCEYII-Dh1ZoVJb.js} +1 -1
  28. package/dist/client/assets/{index-CMsZQS3t.js → index-BQG2YUwc.js} +1 -1
  29. package/dist/client/assets/index-C5IzEHNL.js +760 -0
  30. package/dist/client/assets/{index-BwbjYrNH.js → index-CiSTZTU5.js} +1 -1
  31. package/dist/client/assets/{index-zpHL2aYW.css → index-b9dqo5lW.css} +1 -1
  32. package/dist/client/assets/{infoDiagram-5YYISTIA-Cy_D0LmA.js → infoDiagram-5YYISTIA-BuHIm-Jn.js} +1 -1
  33. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-B3cvnpaf.js → ishikawaDiagram-YF4QCWOH-I8nVafdM.js} +1 -1
  34. package/dist/client/assets/{journeyDiagram-JHISSGLW-IR8sEnrO.js → journeyDiagram-JHISSGLW-shtpF1TZ.js} +1 -1
  35. package/dist/client/assets/{kanban-definition-UN3LZRKU-DHaqk7jz.js → kanban-definition-UN3LZRKU-BsO8TIvo.js} +1 -1
  36. package/dist/client/assets/{linear-BJO3kbAY.js → linear-C3N1YJbK.js} +1 -1
  37. package/dist/client/assets/{mermaid.core-Dwygsmt4.js → mermaid.core-DUTTNZnN.js} +4 -4
  38. package/dist/client/assets/{mindmap-definition-RKZ34NQL-C9XVPJV6.js → mindmap-definition-RKZ34NQL-DEMm3PNd.js} +1 -1
  39. package/dist/client/assets/{pieDiagram-4H26LBE5-CZldRk6l.js → pieDiagram-4H26LBE5-ZWkz7ewh.js} +1 -1
  40. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CY053ghg.js → quadrantDiagram-W4KKPZXB-DSdXKJ0w.js} +1 -1
  41. package/dist/client/assets/{requirementDiagram-4Y6WPE33-DQbMS7j1.js → requirementDiagram-4Y6WPE33-yqSjbYPV.js} +1 -1
  42. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-C5w3huvN.js → sankeyDiagram-5OEKKPKP-yXc5bZhC.js} +1 -1
  43. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-nF1GikPI.js → sequenceDiagram-3UESZ5HK-Z1Nu6haY.js} +1 -1
  44. package/dist/client/assets/{stateDiagram-AJRCARHV-CxjKXGSz.js → stateDiagram-AJRCARHV-DLVVcNhF.js} +1 -1
  45. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DxGjPxxo.js +1 -0
  46. package/dist/client/assets/{timeline-definition-PNZ67QCA-q0ZvTC5H.js → timeline-definition-PNZ67QCA-3TZN84mA.js} +1 -1
  47. package/dist/client/assets/{vennDiagram-CIIHVFJN-CO7sztp2.js → vennDiagram-CIIHVFJN-D8QmAxH6.js} +1 -1
  48. package/dist/client/assets/{wardley-L42UT6IY-JeTZFzC9.js → wardley-L42UT6IY-r7LqMpHU.js} +1 -1
  49. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-COpCQvmO.js → wardleyDiagram-YWT4CUSO-KQreLEne.js} +1 -1
  50. package/dist/client/assets/{xychartDiagram-2RQKCTM6-C78ptl5b.js → xychartDiagram-2RQKCTM6-Bxy2QkZl.js} +1 -1
  51. package/dist/client/index.html +2 -2
  52. package/dist/server/config.d.ts +13 -0
  53. package/dist/server/config.js +27 -0
  54. package/dist/server/config.js.map +1 -1
  55. package/dist/server/db/migrations/030_remote_session.sql +29 -0
  56. package/dist/server/db/migrations/031_release_push.sql +39 -0
  57. package/dist/server/entities/ac/system-prompt.js +6 -6
  58. package/dist/server/entities/ac/system-prompt.js.map +1 -1
  59. package/dist/server/index.js +35 -2
  60. package/dist/server/index.js.map +1 -1
  61. package/dist/server/routes/errors.js +10 -0
  62. package/dist/server/routes/errors.js.map +1 -1
  63. package/dist/server/routes/release-pushes.d.ts +10 -0
  64. package/dist/server/routes/release-pushes.js +68 -0
  65. package/dist/server/routes/release-pushes.js.map +1 -0
  66. package/dist/server/routes/releases.js +9 -0
  67. package/dist/server/routes/releases.js.map +1 -1
  68. package/dist/server/routes/remote-account.d.ts +8 -0
  69. package/dist/server/routes/remote-account.js +49 -0
  70. package/dist/server/routes/remote-account.js.map +1 -0
  71. package/dist/server/services/brief.d.ts +2 -0
  72. package/dist/server/services/brief.js +10 -0
  73. package/dist/server/services/brief.js.map +1 -1
  74. package/dist/server/services/plan.js +6 -6
  75. package/dist/server/services/plan.js.map +1 -1
  76. package/dist/server/services/release-bundle.d.ts +92 -0
  77. package/dist/server/services/release-bundle.js +183 -0
  78. package/dist/server/services/release-bundle.js.map +1 -0
  79. package/dist/server/services/release-push.d.ts +38 -0
  80. package/dist/server/services/release-push.js +179 -0
  81. package/dist/server/services/release-push.js.map +1 -0
  82. package/dist/server/services/release.d.ts +39 -1
  83. package/dist/server/services/release.js +53 -1
  84. package/dist/server/services/release.js.map +1 -1
  85. package/dist/server/services/remote-auth.d.ts +56 -0
  86. package/dist/server/services/remote-auth.js +161 -0
  87. package/dist/server/services/remote-auth.js.map +1 -0
  88. package/dist/server/services/remote-http-client.d.ts +136 -0
  89. package/dist/server/services/remote-http-client.js +172 -0
  90. package/dist/server/services/remote-http-client.js.map +1 -0
  91. package/dist/shared/release-push.d.ts +49 -0
  92. package/dist/shared/release-push.js +9 -0
  93. package/dist/shared/release-push.js.map +1 -0
  94. package/dist/shared/remote-account.d.ts +58 -0
  95. package/dist/shared/remote-account.js +8 -0
  96. package/dist/shared/remote-account.js.map +1 -0
  97. package/dist/shared/types.d.ts +1 -0
  98. package/package.json +2 -1
  99. package/dist/client/assets/channel-mXCQ_joU.js +0 -1
  100. package/dist/client/assets/classDiagram-4FO5ZUOK-CvLk0Sg1.js +0 -1
  101. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CvLk0Sg1.js +0 -1
  102. package/dist/client/assets/index-CUhhC6SY.js +0 -742
  103. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CLYCEwSk.js +0 -1
@@ -0,0 +1,172 @@
1
+ /**
2
+ * M24 — the single abstraction over `fetch` to the remote claude4spec-API.
3
+ * Owned by M24, consumed by future M25; no other module talks to the remote
4
+ * directly. Base URL = `config.remoteApiUrl ?? PROD_REMOTE_URL` (the override is
5
+ * dev/staging only — it is never persisted to `remote_session`, never logged,
6
+ * and is not a secret). The Bearer is injected into owner-only calls only;
7
+ * `/v1/auth/device/*` are unauthenticated.
8
+ *
9
+ * The remote wire contracts mirrored below are the claude4spec-api M02/M03 DTOs
10
+ * (`@c4s/types`), duplicated here as local interfaces because the two repos do
11
+ * not share a package.
12
+ */
13
+ import { createReadStream } from 'node:fs';
14
+ /** Hardcoded production remote. `config.remoteApiUrl` overrides for dev/staging. */
15
+ export const PROD_REMOTE_URL = 'https://claude4spec.inharness.ai';
16
+ /**
17
+ * Thrown when an owner-only remote call returns 401 — the caller must clear the
18
+ * local `remote_session` and force a fresh device flow.
19
+ */
20
+ export class RemoteUnauthorizedError extends Error {
21
+ constructor(message = 'remote session expired') {
22
+ super(message);
23
+ this.name = 'RemoteUnauthorizedError';
24
+ }
25
+ }
26
+ /** Thrown for transport-level failures (connection refused / 5xx / unexpected shape). */
27
+ export class RemoteRequestError extends Error {
28
+ status;
29
+ constructor(message, status) {
30
+ super(message);
31
+ this.status = status;
32
+ this.name = 'RemoteRequestError';
33
+ }
34
+ }
35
+ export class RemoteHttpClient {
36
+ baseUrl;
37
+ constructor(remoteApiUrl) {
38
+ this.baseUrl = (remoteApiUrl ?? PROD_REMOTE_URL).replace(/\/+$/, '');
39
+ }
40
+ get base() {
41
+ return this.baseUrl;
42
+ }
43
+ /** POST /v1/auth/device/code — unauthenticated. Initiates the device flow. */
44
+ async startDeviceFlow() {
45
+ const res = await this.fetchRemote('/v1/auth/device/code', { method: 'POST' });
46
+ if (!res.ok)
47
+ throw new RemoteRequestError(`device/code failed (HTTP ${res.status})`, res.status);
48
+ return (await res.json());
49
+ }
50
+ /**
51
+ * POST /v1/auth/device/token — unauthenticated, authorized by the device_code
52
+ * itself. 200 → token (issued once); 400 → polling-state envelope
53
+ * (authorization_pending / slow_down / terminal).
54
+ */
55
+ async pollDeviceToken(deviceCode) {
56
+ const res = await this.fetchRemote('/v1/auth/device/token', {
57
+ method: 'POST',
58
+ headers: { 'content-type': 'application/json' },
59
+ body: JSON.stringify({ device_code: deviceCode }),
60
+ });
61
+ if (res.ok) {
62
+ return { ok: true, token: (await res.json()) };
63
+ }
64
+ if (res.status === 400) {
65
+ const body = (await res.json().catch(() => null));
66
+ if (body?.error)
67
+ return { ok: false, error: body.error, description: body.error_description };
68
+ }
69
+ throw new RemoteRequestError(`device/token failed (HTTP ${res.status})`, res.status);
70
+ }
71
+ /** GET /v1/account — owner-only (Bearer). 401 → RemoteUnauthorizedError. */
72
+ async getAccount(accessToken) {
73
+ const res = await this.fetchRemote('/v1/account', {
74
+ method: 'GET',
75
+ headers: { authorization: `Bearer ${accessToken}` },
76
+ });
77
+ if (res.status === 401)
78
+ throw new RemoteUnauthorizedError();
79
+ if (!res.ok)
80
+ throw new RemoteRequestError(`GET /v1/account failed (HTTP ${res.status})`, res.status);
81
+ return (await res.json());
82
+ }
83
+ /**
84
+ * POST /v1/projects — first push. Streams the bundle as octet-stream and
85
+ * creates a new remote project named `projectName`. 401 → RemoteUnauthorizedError;
86
+ * any other non-2xx → RemoteRequestError (message from the remote error envelope).
87
+ */
88
+ async createProject(accessToken, payload, projectName) {
89
+ const res = await this.streamBundle('/v1/projects', accessToken, payload, {
90
+ 'x-project-name': projectName,
91
+ });
92
+ if (res.status === 401)
93
+ throw new RemoteUnauthorizedError();
94
+ if (!res.ok) {
95
+ throw new RemoteRequestError(await this.errorMessageFrom(res, `POST /v1/projects failed (HTTP ${res.status})`), res.status);
96
+ }
97
+ return (await res.json());
98
+ }
99
+ /**
100
+ * POST /v1/projects/:remoteProjectId/releases — subsequent push (no
101
+ * X-Project-Name). 200 = deduplicated hit, 201 = fresh release; both carry the
102
+ * `deduplicated` flag. 401 → RemoteUnauthorizedError; other non-2xx → RemoteRequestError.
103
+ */
104
+ async pushRelease(accessToken, remoteProjectId, payload) {
105
+ const res = await this.streamBundle(`/v1/projects/${encodeURIComponent(remoteProjectId)}/releases`, accessToken, payload);
106
+ if (res.status === 401)
107
+ throw new RemoteUnauthorizedError();
108
+ if (!res.ok) {
109
+ throw new RemoteRequestError(await this.errorMessageFrom(res, `POST /v1/projects/:id/releases failed (HTTP ${res.status})`), res.status);
110
+ }
111
+ return (await res.json());
112
+ }
113
+ /** Streams `tarGzPath` as application/octet-stream with the integrity + auth headers. */
114
+ streamBundle(path, accessToken, payload, extraHeaders = {}) {
115
+ const headers = {
116
+ 'content-type': 'application/octet-stream',
117
+ 'content-length': String(payload.sizeBytes),
118
+ 'x-content-sha256': payload.sha256,
119
+ authorization: `Bearer ${accessToken}`,
120
+ ...extraHeaders,
121
+ };
122
+ // `duplex: 'half'` is required by undici when the body is a stream; it is not
123
+ // yet in the DOM RequestInit type, hence the cast.
124
+ return this.fetchRemote(path, {
125
+ method: 'POST',
126
+ headers,
127
+ body: createReadStream(payload.tarGzPath),
128
+ duplex: 'half',
129
+ });
130
+ }
131
+ /** Best-effort human message from a remote error response (`{error:{message|code}}` or NestJS `{message}`). */
132
+ async errorMessageFrom(res, fallback) {
133
+ try {
134
+ const body = (await res.json());
135
+ if (body?.error?.message)
136
+ return body.error.message;
137
+ if (body?.error?.code)
138
+ return body.error.code;
139
+ if (typeof body?.message === 'string')
140
+ return body.message;
141
+ }
142
+ catch {
143
+ /* non-JSON body — fall through */
144
+ }
145
+ return fallback;
146
+ }
147
+ async fetchRemote(path, init) {
148
+ try {
149
+ return await fetch(`${this.baseUrl}${path}`, init);
150
+ }
151
+ catch (err) {
152
+ throw new RemoteRequestError(`request to remote ${path} failed: ${err.message}`);
153
+ }
154
+ }
155
+ }
156
+ /**
157
+ * Startup reachability check for an explicit `config.remoteApiUrl` override.
158
+ * "Reachable" = the host answers at all (any HTTP status); only a transport
159
+ * failure / timeout counts as unreachable. No fallback to PROD_REMOTE_URL — an
160
+ * explicit override must be honoured or reported (brief §1). Throws with the
161
+ * exact contract message.
162
+ */
163
+ export async function assertRemoteApiReachable(remoteApiUrl, timeoutMs = 3000) {
164
+ const base = remoteApiUrl.replace(/\/+$/, '');
165
+ try {
166
+ await fetch(`${base}/v1/health`, { method: 'HEAD', signal: AbortSignal.timeout(timeoutMs) });
167
+ }
168
+ catch {
169
+ throw new Error(`config.json: field 'remoteApiUrl': invalid URL or unreachable host`);
170
+ }
171
+ }
172
+ //# sourceMappingURL=remote-http-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-http-client.js","sourceRoot":"","sources":["../../../src/server/services/remote-http-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * M25 Release Push — DTOs exposed by `/api/release-pushes/*` to the c4s client.
3
+ * These are M25's OWN surface, decoupled from the remote-API wire format
4
+ * (claude4spec-api). The backend (`release-push.ts`) maps a `release_push` row
5
+ * onto these camelCase shapes and joins `spec_release` for the nested release
6
+ * meta (so the UI does not need a second fetch).
7
+ */
8
+ /** Body of `POST /api/release-pushes`. */
9
+ export interface ReleasePushRequest {
10
+ /** FK to `spec_release.id` — the local release to push. */
11
+ releaseId: number;
12
+ }
13
+ /**
14
+ * Response of `POST /api/release-pushes` (success or dedup hit) and
15
+ * `GET /api/release-pushes/:id`. A full `release_push` row in camelCase plus a
16
+ * nested snapshot of the local release meta. GET endpoints return rows of both
17
+ * statuses; POST never returns a `status='error'` row (errors → 502 with a
18
+ * different envelope).
19
+ */
20
+ export interface ReleasePushResponse {
21
+ id: number;
22
+ releaseId: number;
23
+ release: {
24
+ id: number;
25
+ name: string;
26
+ };
27
+ remoteProjectId: string;
28
+ /** NULL/undefined for status='error'. */
29
+ remoteReleaseId?: string;
30
+ /** NULL/undefined for status='error'. */
31
+ remoteReleaseSequence?: number;
32
+ /** lowercase hex64 — /^[0-9a-f]{64}$/. */
33
+ contentSha256: string;
34
+ contentSizeBytes: number;
35
+ deduplicated: boolean;
36
+ pushedByAccountId: string;
37
+ /** Cached identity — may be stale. */
38
+ pushedByAccountEmail?: string;
39
+ bundleSchemaVersion: number;
40
+ status: 'success' | 'error';
41
+ /** Only for status='error'. */
42
+ errorMessage?: string;
43
+ /** ISO 8601. */
44
+ pushedAt: string;
45
+ }
46
+ /** Response of `GET /api/release-pushes`. */
47
+ export interface ReleasePushListResponse {
48
+ items: ReleasePushResponse[];
49
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * M25 Release Push — DTOs exposed by `/api/release-pushes/*` to the c4s client.
3
+ * These are M25's OWN surface, decoupled from the remote-API wire format
4
+ * (claude4spec-api). The backend (`release-push.ts`) maps a `release_push` row
5
+ * onto these camelCase shapes and joins `spec_release` for the nested release
6
+ * meta (so the UI does not need a second fetch).
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=release-push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-push.js","sourceRoot":"","sources":["../../src/shared/release-push.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * M24 Remote Account — DTOs exposed by `/api/remote-account/*` to the c4s
3
+ * client. These are M24's OWN surface, intentionally decoupled from the
4
+ * remote-API wire format (claude4spec-api `@c4s/types`). The backend
5
+ * (`remote-auth.ts`) maps the remote's device-flow contract onto these shapes.
6
+ */
7
+ /**
8
+ * `POST /api/remote-account/login/start` — device flow initiated. The raw
9
+ * `device_code` is NOT exposed: the backend keeps it in memory (single flow per
10
+ * c4s instance) and supplies it itself when polling, so the secret never lands
11
+ * in the browser.
12
+ */
13
+ export interface DeviceLoginStartResponse {
14
+ /** Short human-readable code (format `XXXX-XXXX`) typed on the verification page. */
15
+ user_code: string;
16
+ /** Verification page URL without the code (fallback). */
17
+ verification_uri: string;
18
+ /** Verification URL with the code prefilled — primary CTA (qr-code-ready). */
19
+ verification_uri_complete: string;
20
+ /** Seconds between polls; the client increases it when the remote says `slow_down`. */
21
+ interval: number;
22
+ /** Flow TTL in seconds; once exceeded the flow goes terminal `expired`. */
23
+ expires_in: number;
24
+ }
25
+ /**
26
+ * Status surfaced by `POST /api/remote-account/login/poll`. Non-terminal:
27
+ * `pending` / `slow_down` (keep polling). Terminal: `authorized` (session
28
+ * saved) and `expired` / `denied` / `invalid` (stop). Mapped from the remote
29
+ * device-token enum (`authorization_pending | slow_down | expired_token |
30
+ * access_denied | invalid_grant`).
31
+ */
32
+ export type DeviceLoginStatus = 'pending' | 'slow_down' | 'authorized' | 'expired' | 'denied' | 'invalid';
33
+ export interface DeviceLoginPollResponse {
34
+ status: DeviceLoginStatus;
35
+ /** Only for `slow_down` — new recommended interval (seconds). */
36
+ interval?: number;
37
+ /** User-facing message for terminal errors. */
38
+ message?: string;
39
+ /** Only for `authorized` — lets the UI jump straight to "connected as X" without a follow-up GET. */
40
+ account?: RemoteAccountResponse;
41
+ }
42
+ /**
43
+ * `GET /api/remote-account` — the sidebar's identity source. NEVER exposes
44
+ * `access_token`. Stable contract consumed by the sidebar (TanStack Query key
45
+ * `["remote-account"]`) and, later, by M25 publish.
46
+ */
47
+ export interface RemoteAccountResponse {
48
+ /** `true` when a `remote_session` row exists. */
49
+ connected: boolean;
50
+ /** UUID of the remote account (`remote_session.remote_account_id`). */
51
+ remoteAccountId?: string;
52
+ /** UI label — the only "connected as X" identity the remote exposes. */
53
+ accountEmail?: string;
54
+ /** `deactivated` blocks publish (M25). */
55
+ accountStatus?: 'active' | 'deactivated';
56
+ /** ISO 8601 from `remote_session.connected_at`. */
57
+ connectedAt?: string;
58
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * M24 Remote Account — DTOs exposed by `/api/remote-account/*` to the c4s
3
+ * client. These are M24's OWN surface, intentionally decoupled from the
4
+ * remote-API wire format (claude4spec-api `@c4s/types`). The backend
5
+ * (`remote-auth.ts`) maps the remote's device-flow contract onto these shapes.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=remote-account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-account.js","sourceRoot":"","sources":["../../src/shared/remote-account.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -67,6 +67,7 @@ export type WsEvent = {
67
67
  } | {
68
68
  kind: 'briefs:changed';
69
69
  path?: string;
70
+ origin?: 'server' | 'external';
70
71
  } | {
71
72
  kind: 'patches:changed';
72
73
  path?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inharness-ai/claude4spec",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Plan the whole system before your agent writes a line of code. Local-first planning layer with structured entities and typed relations.",
5
5
  "license": "MIT",
6
6
  "author": "Michael Tomala <mi.tomala@gmail.com>",
@@ -87,6 +87,7 @@
87
87
  "react-markdown": "^9.1.0",
88
88
  "rehype-highlight": "^7.0.2",
89
89
  "remark-gfm": "^4.0.1",
90
+ "tar": "^7.5.15",
90
91
  "tiptap-markdown": "^0.8.10",
91
92
  "ws": "^8.18.0",
92
93
  "zod": "^4.3.6",
@@ -1 +0,0 @@
1
- import{ai as o,aj as n}from"./mermaid.core-Dwygsmt4.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-727SXJPM-CvT-ppRD.js";import{_ as i}from"./mermaid.core-Dwygsmt4.js";import"./chunk-FMBD7UC4-DlnsCvyP.js";import"./chunk-ND2GUHAM-Cv4kIfqi.js";import"./chunk-55IACEB6-B513D_Oz.js";import"./chunk-2J33WTMH-Bwc9B4Id.js";import"./index-CUhhC6SY.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-727SXJPM-CvT-ppRD.js";import{_ as i}from"./mermaid.core-Dwygsmt4.js";import"./chunk-FMBD7UC4-DlnsCvyP.js";import"./chunk-ND2GUHAM-Cv4kIfqi.js";import"./chunk-55IACEB6-B513D_Oz.js";import"./chunk-2J33WTMH-Bwc9B4Id.js";import"./index-CUhhC6SY.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};