@asc-agent/runtime 0.1.0 → 0.2.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.
@@ -0,0 +1,29 @@
1
+ export type ProfileOrigin = 'built-in' | 'external';
2
+ export type ProfileLocation = {
3
+ id: string;
4
+ origin: ProfileOrigin;
5
+ /** `profile.json` 의 절대 경로. 파일이 아직 없을 수도 있다 — 읽는 쪽이 그 사실을 만난다. */
6
+ path: string;
7
+ };
8
+ export type ProfileRoots = {
9
+ /** 설치된 배포본의 뿌리. `profiles/` 가 그 아래 있다. */
10
+ installRoot: string;
11
+ /** 사용자 소유 Profile 디렉터리. 보통 `ASC_HOME/profiles`. 없으면 external은 없는 것이다. */
12
+ externalRoot?: string;
13
+ };
14
+ /** 왜 Profile을 고르지 못했는가. 문장이 아니라 코드로 든다 — Surface가 다르게 말해야 한다. */
15
+ export type ProfileSourceCode = 'INVALID_PROFILE_ID' | 'PROFILE_COLLISION' | 'PROFILE_ESCAPES_ROOT' | 'PROFILE_ID_MISMATCH';
16
+ export declare class ProfileSourceError extends Error {
17
+ code: ProfileSourceCode;
18
+ constructor(code: ProfileSourceCode, message: string);
19
+ }
20
+ export declare function assertProfileId(id: string): void;
21
+ /** 이 뿌리들 아래에 실제로 있는 Profile 전부. external이 먼저 온다. */
22
+ export declare function listProfileLocations(roots: ProfileRoots): Promise<ProfileLocation[]>;
23
+ /**
24
+ * 이 id의 Profile은 어디 있는가.
25
+ *
26
+ * 아무 데도 없으면 **built-in 자리를 돌려준다** — 파일이 없다는 사실은 읽는 쪽에서
27
+ * 그대로 드러나야 하고, 그 오류 모양은 v0.1과 같아야 한다.
28
+ */
29
+ export declare function resolveProfileLocation(id: string, roots: ProfileRoots): Promise<ProfileLocation>;
@@ -0,0 +1,139 @@
1
+ // Profile이 어디서 오는가 — 설치된 배포본 안, 그리고 사용자 소유 공간.
2
+ //
3
+ // v0.1까지 Profile은 **설치 경로 안에만** 있었다. 그래서 공개 패키지를 설치한 사람은
4
+ // 자기 프로젝트의 Profile을 쓸 방법이 없었다 — 팀에 배포할 수 없다는 뜻이다.
5
+ // 여기서 여는 것은 그 한 갈래다: `ASC_HOME/profiles/<id>/profile.json`.
6
+ //
7
+ // 자리를 고르는 규칙이 이 파일의 전부다:
8
+ // 1. 사람이 명시한 것 Surface가 이미 id로 넘긴다
9
+ // 2. 사용자 소유 external ASC_HOME — 팀이 나눠 갖는 실 Profile이 여기 온다
10
+ // 3. 배포본 내장 built-in 예시·fixture. 아무것도 없을 때의 바닥
11
+ //
12
+ // **같은 id가 양쪽에 있으면 멈춘다.** 조용히 하나를 고르면 "무엇을 읽었는가"를 사람이
13
+ // 알 수 없고, 그 답이 정책이 되므로 틀린 쪽으로 조용히 도는 것보다 서는 편이 낫다.
14
+ //
15
+ // Profile은 코드가 아니라 데이터다. 여기서 하는 일은 **경로를 고르는 것뿐**이고,
16
+ // 읽기·검증·digest는 기존 resolver 계약(load.ts)이 그대로 한다.
17
+ import { constants } from 'node:fs';
18
+ import { access, readdir, realpath } from 'node:fs/promises';
19
+ import { isAbsolute, join, relative, resolve, sep } from 'node:path';
20
+ export class ProfileSourceError extends Error {
21
+ code;
22
+ constructor(code, message) {
23
+ super(message);
24
+ this.name = 'ProfileSourceError';
25
+ this.code = code;
26
+ }
27
+ }
28
+ /**
29
+ * Profile id는 **디렉터리 이름 한 칸**이다.
30
+ *
31
+ * 경로 조각을 허용하면 id 하나로 `profiles/` 밖의 파일을 읽게 된다 — `../../secrets`
32
+ * 같은 것. 그래서 여기서 문법으로 막고, 아래에서 실제 경로가 뿌리 안에 있는지 한 번 더 본다
33
+ * (문법만 믿지 않는다 — symlink는 문법을 통과한다).
34
+ */
35
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
36
+ export function assertProfileId(id) {
37
+ if (!SAFE_ID.test(id) || id === '.' || id === '..') {
38
+ throw new ProfileSourceError('INVALID_PROFILE_ID', `'${id}' is not a profile id — use a single name made of letters, digits, '.', '_' or '-'`);
39
+ }
40
+ }
41
+ /** 글자만 보고 판단한다. 첫 번째 자물쇠 — symlink·junction은 여기를 그냥 통과한다. */
42
+ function withinLexically(root, target) {
43
+ const rel = relative(resolve(root), resolve(target));
44
+ return rel !== '' && !rel.startsWith(`..${sep}`) && rel !== '..' && !isAbsolute(rel);
45
+ }
46
+ /**
47
+ * **실제로** 그 뿌리 안인가. 두 번째 자물쇠다.
48
+ *
49
+ * 글자 검사만으로는 부족하다는 것을 독립 검증이 실물로 보였다 — Windows junction
50
+ * (`mklink /J`)이나 symlink를 `profiles/` 안에 만들면 이름은 한 칸이고 경로도 뿌리 안처럼
51
+ * 보이는데, 실제 파일은 바깥에 있다. 그 파일이 프로젝트의 정책이 되면 lock에 적히는
52
+ * 출처마저 link 경로라 사람이 진짜 자리를 알 수 없다.
53
+ *
54
+ * 그래서 존재하는 것은 realpath로 한 번 더 본다. 없는 경로는 판정 대상이 아니다.
55
+ */
56
+ async function withinReally(root, target) {
57
+ try {
58
+ const [realRoot, realTarget] = await Promise.all([realpath(root), realpath(target)]);
59
+ return withinLexically(realRoot, realTarget);
60
+ }
61
+ catch {
62
+ // 아직 없는 파일이면 글자 판단만으로 충분하다 — 읽는 쪽에서 없다는 사실을 만난다.
63
+ return withinLexically(root, target);
64
+ }
65
+ }
66
+ const profilePath = (root, id) => join(root, id, 'profile.json');
67
+ const exists = async (path) => {
68
+ try {
69
+ await access(path, constants.F_OK);
70
+ return true;
71
+ }
72
+ catch {
73
+ return false;
74
+ }
75
+ };
76
+ /** 이 뿌리들 아래에 실제로 있는 Profile 전부. external이 먼저 온다. */
77
+ export async function listProfileLocations(roots) {
78
+ const found = [];
79
+ const dirs = [
80
+ ['external', roots.externalRoot],
81
+ ['built-in', join(roots.installRoot, 'profiles')],
82
+ ];
83
+ for (const [origin, dir] of dirs) {
84
+ if (!dir)
85
+ continue;
86
+ let entries;
87
+ try {
88
+ entries = await readdir(dir, { withFileTypes: true });
89
+ }
90
+ catch {
91
+ continue; // 없는 디렉터리는 "Profile 0개"다. 오류가 아니다.
92
+ }
93
+ for (const entry of entries) {
94
+ // junction·symlink는 Windows에서 `isDirectory()` 가 아니다. 목록에서만 빼면
95
+ // "후보에는 없는데 --profile 로는 붙는" 상태가 되므로 여기서도 같이 본다 —
96
+ // 발견과 해석이 다른 답을 하면 사람은 둘 다 못 믿는다.
97
+ if (!entry.isDirectory() && !entry.isSymbolicLink())
98
+ continue;
99
+ if (!SAFE_ID.test(entry.name))
100
+ continue; // 이름이 문법 밖이면 고를 수 없는 것이다
101
+ const path = profilePath(dir, entry.name);
102
+ if (!(await withinReally(dir, path)))
103
+ continue;
104
+ if (await exists(path))
105
+ found.push({ id: entry.name, origin, path });
106
+ }
107
+ }
108
+ return found;
109
+ }
110
+ /**
111
+ * 이 id의 Profile은 어디 있는가.
112
+ *
113
+ * 아무 데도 없으면 **built-in 자리를 돌려준다** — 파일이 없다는 사실은 읽는 쪽에서
114
+ * 그대로 드러나야 하고, 그 오류 모양은 v0.1과 같아야 한다.
115
+ */
116
+ export async function resolveProfileLocation(id, roots) {
117
+ assertProfileId(id);
118
+ const builtInDir = join(roots.installRoot, 'profiles');
119
+ const builtIn = profilePath(builtInDir, id);
120
+ const externalDir = roots.externalRoot;
121
+ const external = externalDir ? profilePath(externalDir, id) : undefined;
122
+ if (external && !withinLexically(externalDir, external)) {
123
+ throw new ProfileSourceError('INVALID_PROFILE_ID', `'${id}' escapes the profile directory`);
124
+ }
125
+ const hasExternal = external ? await exists(external) : false;
126
+ if (external && hasExternal && !(await withinReally(externalDir, external))) {
127
+ throw new ProfileSourceError('PROFILE_ESCAPES_ROOT', `'${id}' points outside ${externalDir} — a link leads to another place on disk. ` +
128
+ 'Put the profile itself in the directory: policy must not come from somewhere the ' +
129
+ 'recorded source does not name.');
130
+ }
131
+ const hasBuiltIn = await exists(builtIn);
132
+ if (hasExternal && hasBuiltIn) {
133
+ throw new ProfileSourceError('PROFILE_COLLISION', `two profiles claim the id '${id}' — ${external} and ${builtIn}. ` +
134
+ 'Rename one of them: which policy applies must not depend on lookup order.');
135
+ }
136
+ if (hasExternal)
137
+ return { id, origin: 'external', path: external };
138
+ return { id, origin: 'built-in', path: builtIn };
139
+ }
@@ -32,15 +32,15 @@ export declare const Workspace: z.ZodObject<{
32
32
  createdAt: z.ZodString;
33
33
  lastSeenAt: z.ZodString;
34
34
  }, "strip", z.ZodTypeAny, {
35
- lastSeenAt: string;
36
35
  workspaceId: string;
37
36
  aliases: string[];
38
37
  adoptionScope: "local" | "project";
39
38
  createdAt: string;
40
- }, {
41
39
  lastSeenAt: string;
40
+ }, {
42
41
  workspaceId: string;
43
42
  createdAt: string;
43
+ lastSeenAt: string;
44
44
  aliases?: string[] | undefined;
45
45
  adoptionScope?: "local" | "project" | undefined;
46
46
  }>;
@@ -10,15 +10,15 @@ declare const LocatorEntry: z.ZodObject<{
10
10
  observedAt: z.ZodString;
11
11
  }, "strip", z.ZodTypeAny, {
12
12
  observedAt: string;
13
- root: string;
14
13
  platform: string;
15
14
  workspaceId: string;
15
+ root: string;
16
16
  kind?: "checkout" | "worktree" | undefined;
17
17
  }, {
18
18
  observedAt: string;
19
- root: string;
20
19
  platform: string;
21
20
  workspaceId: string;
21
+ root: string;
22
22
  kind?: "checkout" | "worktree" | undefined;
23
23
  }>;
24
24
  export type LocatorEntry = z.infer<typeof LocatorEntry>;
@@ -31,15 +31,15 @@ export declare const WorkspaceIndex: z.ZodObject<{
31
31
  createdAt: z.ZodString;
32
32
  lastSeenAt: z.ZodString;
33
33
  }, "strip", z.ZodTypeAny, {
34
- lastSeenAt: string;
35
34
  workspaceId: string;
36
35
  aliases: string[];
37
36
  adoptionScope: "local" | "project";
38
37
  createdAt: string;
39
- }, {
40
38
  lastSeenAt: string;
39
+ }, {
41
40
  workspaceId: string;
42
41
  createdAt: string;
42
+ lastSeenAt: string;
43
43
  aliases?: string[] | undefined;
44
44
  adoptionScope?: "local" | "project" | undefined;
45
45
  }>>>;
@@ -53,47 +53,47 @@ export declare const WorkspaceIndex: z.ZodObject<{
53
53
  observedAt: z.ZodString;
54
54
  }, "strip", z.ZodTypeAny, {
55
55
  observedAt: string;
56
- root: string;
57
56
  platform: string;
58
57
  workspaceId: string;
58
+ root: string;
59
59
  kind?: "checkout" | "worktree" | undefined;
60
60
  }, {
61
61
  observedAt: string;
62
- root: string;
63
62
  platform: string;
64
63
  workspaceId: string;
64
+ root: string;
65
65
  kind?: "checkout" | "worktree" | undefined;
66
66
  }>>>;
67
67
  }, "strip", z.ZodTypeAny, {
68
68
  version: 1;
69
69
  workspaces: Record<string, {
70
- lastSeenAt: string;
71
70
  workspaceId: string;
72
71
  aliases: string[];
73
72
  adoptionScope: "local" | "project";
74
73
  createdAt: string;
74
+ lastSeenAt: string;
75
75
  }>;
76
76
  locators: Record<string, {
77
77
  observedAt: string;
78
- root: string;
79
78
  platform: string;
80
79
  workspaceId: string;
80
+ root: string;
81
81
  kind?: "checkout" | "worktree" | undefined;
82
82
  }>;
83
83
  }, {
84
84
  version: 1;
85
85
  workspaces?: Record<string, {
86
- lastSeenAt: string;
87
86
  workspaceId: string;
88
87
  createdAt: string;
88
+ lastSeenAt: string;
89
89
  aliases?: string[] | undefined;
90
90
  adoptionScope?: "local" | "project" | undefined;
91
91
  }> | undefined;
92
92
  locators?: Record<string, {
93
93
  observedAt: string;
94
- root: string;
95
94
  platform: string;
96
95
  workspaceId: string;
96
+ root: string;
97
97
  kind?: "checkout" | "worktree" | undefined;
98
98
  }> | undefined;
99
99
  }>;
@@ -11,16 +11,16 @@ export declare const CanonicalSourceSpec: z.ZodObject<{
11
11
  id: string;
12
12
  paths: string[];
13
13
  provider: "git" | "github";
14
+ $comment?: string | undefined;
14
15
  remote?: string | undefined;
15
16
  ref?: string | undefined;
16
- $comment?: string | undefined;
17
17
  }, {
18
18
  id: string;
19
19
  provider: "git" | "github";
20
20
  paths?: string[] | undefined;
21
+ $comment?: string | undefined;
21
22
  remote?: string | undefined;
22
23
  ref?: string | undefined;
23
- $comment?: string | undefined;
24
24
  }>;
25
25
  export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, unknown, unknown>, z.ZodObject<{
26
26
  schemaVersion: z.ZodLiteral<1>;
@@ -63,34 +63,34 @@ export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, un
63
63
  id: string;
64
64
  paths: string[];
65
65
  provider: "git" | "github";
66
+ $comment?: string | undefined;
66
67
  remote?: string | undefined;
67
68
  ref?: string | undefined;
68
- $comment?: string | undefined;
69
69
  }, {
70
70
  id: string;
71
71
  provider: "git" | "github";
72
72
  paths?: string[] | undefined;
73
+ $comment?: string | undefined;
73
74
  remote?: string | undefined;
74
75
  ref?: string | undefined;
75
- $comment?: string | undefined;
76
76
  }>, "many">>;
77
77
  }, "strip", z.ZodTypeAny, {
78
78
  sources: {
79
79
  id: string;
80
80
  paths: string[];
81
81
  provider: "git" | "github";
82
+ $comment?: string | undefined;
82
83
  remote?: string | undefined;
83
84
  ref?: string | undefined;
84
- $comment?: string | undefined;
85
85
  }[];
86
86
  }, {
87
87
  sources?: {
88
88
  id: string;
89
89
  provider: "git" | "github";
90
90
  paths?: string[] | undefined;
91
+ $comment?: string | undefined;
91
92
  remote?: string | undefined;
92
93
  ref?: string | undefined;
93
- $comment?: string | undefined;
94
94
  }[] | undefined;
95
95
  }>>;
96
96
  monitor: z.ZodDefault<z.ZodObject<{
@@ -242,20 +242,21 @@ export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, un
242
242
  capabilities: string[];
243
243
  asc?: string | undefined;
244
244
  };
245
+ project: {
246
+ scm: string;
247
+ repository: string;
248
+ };
249
+ schemaVersion: 1;
245
250
  canonical: {
246
251
  sources: {
247
252
  id: string;
248
253
  paths: string[];
249
254
  provider: "git" | "github";
255
+ $comment?: string | undefined;
250
256
  remote?: string | undefined;
251
257
  ref?: string | undefined;
252
- $comment?: string | undefined;
253
258
  }[];
254
259
  };
255
- project: {
256
- scm: string;
257
- repository: string;
258
- };
259
260
  policy: {
260
261
  hardDeny: string[];
261
262
  softDeny: string[];
@@ -265,7 +266,6 @@ export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, un
265
266
  lockedSettings: string[];
266
267
  unionLists?: Record<string, string[]> | undefined;
267
268
  };
268
- schemaVersion: 1;
269
269
  optionalCapabilities: string[];
270
270
  workflow: {
271
271
  taskSource: string[];
@@ -273,6 +273,7 @@ export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, un
273
273
  blockSource?: string | undefined;
274
274
  };
275
275
  terminology: Record<string, string>;
276
+ $comment?: string | undefined;
276
277
  ownership?: Record<string, {
277
278
  paths: string[];
278
279
  authorities: string[];
@@ -282,7 +283,6 @@ export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, un
282
283
  resource: string;
283
284
  adapter: string;
284
285
  }[] | undefined;
285
- $comment?: string | undefined;
286
286
  }, {
287
287
  id: string;
288
288
  project: {
@@ -301,14 +301,15 @@ export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, un
301
301
  capabilities?: string[] | undefined;
302
302
  asc?: string | undefined;
303
303
  } | undefined;
304
+ $comment?: string | undefined;
304
305
  canonical?: {
305
306
  sources?: {
306
307
  id: string;
307
308
  provider: "git" | "github";
308
309
  paths?: string[] | undefined;
310
+ $comment?: string | undefined;
309
311
  remote?: string | undefined;
310
312
  ref?: string | undefined;
311
- $comment?: string | undefined;
312
313
  }[] | undefined;
313
314
  } | undefined;
314
315
  ownership?: Record<string, {
@@ -329,7 +330,6 @@ export declare const ProjectProfile: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, un
329
330
  lockedSettings?: string[] | undefined;
330
331
  unionLists?: Record<string, string[]> | undefined;
331
332
  } | undefined;
332
- $comment?: string | undefined;
333
333
  optionalCapabilities?: string[] | undefined;
334
334
  workflow?: {
335
335
  $comment?: string | undefined;
@@ -371,6 +371,7 @@ export declare const OperationalPreset: z.ZodPipeline<z.ZodEffects<z.ZodUnknown,
371
371
  }>>;
372
372
  }, "strip", z.ZodTypeAny, {
373
373
  id: string;
374
+ schemaVersion: 1;
374
375
  policy: {
375
376
  hardDeny?: string[] | undefined;
376
377
  softDeny?: string[] | undefined;
@@ -380,11 +381,11 @@ export declare const OperationalPreset: z.ZodPipeline<z.ZodEffects<z.ZodUnknown,
380
381
  lockedSettings?: string[] | undefined;
381
382
  unionLists?: Record<string, string[]> | undefined;
382
383
  };
383
- schemaVersion: 1;
384
384
  $comment?: string | undefined;
385
385
  }, {
386
386
  id: string;
387
387
  schemaVersion: 1;
388
+ $comment?: string | undefined;
388
389
  policy?: {
389
390
  hardDeny?: string[] | undefined;
390
391
  softDeny?: string[] | undefined;
@@ -394,7 +395,6 @@ export declare const OperationalPreset: z.ZodPipeline<z.ZodEffects<z.ZodUnknown,
394
395
  lockedSettings?: string[] | undefined;
395
396
  unionLists?: Record<string, string[]> | undefined;
396
397
  } | undefined;
397
- $comment?: string | undefined;
398
398
  }>>;
399
399
  export type OperationalPreset = z.infer<typeof OperationalPreset>;
400
400
  /**
@@ -491,6 +491,7 @@ export declare const UserOverride: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, unkn
491
491
  realtime?: boolean | undefined;
492
492
  roles?: string[] | undefined;
493
493
  };
494
+ schemaVersion: 1;
494
495
  approval: {
495
496
  preferredChannel?: string | undefined;
496
497
  messenger?: {
@@ -507,7 +508,6 @@ export declare const UserOverride: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, unkn
507
508
  lockedSettings?: string[] | undefined;
508
509
  unionLists?: Record<string, string[]> | undefined;
509
510
  };
510
- schemaVersion: 1;
511
511
  identity: Record<string, string>;
512
512
  monitorIdentities: string[];
513
513
  $comment?: string | undefined;
@@ -520,6 +520,7 @@ export declare const UserOverride: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, unkn
520
520
  realtime?: boolean | undefined;
521
521
  roles?: string[] | undefined;
522
522
  } | undefined;
523
+ $comment?: string | undefined;
523
524
  approval?: {
524
525
  preferredChannel?: string | undefined;
525
526
  messenger?: {
@@ -536,7 +537,6 @@ export declare const UserOverride: z.ZodPipeline<z.ZodEffects<z.ZodUnknown, unkn
536
537
  lockedSettings?: string[] | undefined;
537
538
  unionLists?: Record<string, string[]> | undefined;
538
539
  } | undefined;
539
- $comment?: string | undefined;
540
540
  identity?: Record<string, string> | undefined;
541
541
  monitorIdentities?: string[] | undefined;
542
542
  }>>;
@@ -586,13 +586,13 @@ export declare const ProfileLock: z.ZodObject<{
586
586
  configurationDigest: z.ZodString;
587
587
  generatedAt: z.ZodString;
588
588
  }, "strip", z.ZodTypeAny, {
589
+ schemaVersion: 1;
589
590
  profile: {
590
591
  id: string;
591
592
  source: string;
592
593
  digest: string;
593
594
  };
594
595
  capabilities: string[];
595
- schemaVersion: 1;
596
596
  ascCore: {
597
597
  version: string;
598
598
  commit?: string | undefined;
@@ -607,12 +607,12 @@ export declare const ProfileLock: z.ZodObject<{
607
607
  } | undefined;
608
608
  overrideDigest?: string | undefined;
609
609
  }, {
610
+ schemaVersion: 1;
610
611
  profile: {
611
612
  id: string;
612
613
  source: string;
613
614
  digest: string;
614
615
  };
615
- schemaVersion: 1;
616
616
  ascCore: {
617
617
  version: string;
618
618
  commit?: string | undefined;
package/package.json CHANGED
@@ -1,55 +1,55 @@
1
- {
2
- "name": "@asc-agent/runtime",
3
- "version": "0.1.0",
4
- "description": "ASC (Agent Session Control) — local-first human-in-the-loop agent control plane: core, CLI, and adapters",
5
- "keywords": [
6
- "agent",
7
- "control-plane",
8
- "human-in-the-loop",
9
- "claude-code",
10
- "local-first",
11
- "session"
12
- ],
13
- "homepage": "https://github.com/colosair/asc#readme",
14
- "bugs": {
15
- "url": "https://github.com/colosair/asc/issues"
16
- },
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/colosair/asc.git",
20
- "directory": "packages/runtime"
21
- },
22
- "author": "colosair (https://github.com/colosair)",
23
- "type": "module",
24
- "bin": {
25
- "asc": "./dist/cli/asc.js"
26
- },
27
- "main": "./dist/cli/asc.js",
28
- "types": "./dist/cli/asc.d.ts",
29
- "exports": {
30
- ".": {
31
- "types": "./dist/cli/asc.d.ts",
32
- "default": "./dist/cli/asc.js"
33
- }
34
- },
35
- "files": [
36
- "dist",
37
- "README.md"
38
- ],
39
- "engines": {
40
- "node": ">=24"
41
- },
42
- "scripts": {
43
- "build": "node scripts/build.mjs",
44
- "prepack": "node scripts/build.mjs",
45
- "test": "node --test \"tests/*.test.ts\"",
46
- "dist:smoke": "node scripts/dist-smoke.mjs"
47
- },
48
- "dependencies": {
49
- "zod": "^3.25.76"
50
- },
51
- "license": "ISC",
52
- "publishConfig": {
53
- "access": "public"
54
- }
55
- }
1
+ {
2
+ "name": "@asc-agent/runtime",
3
+ "version": "0.2.1",
4
+ "description": "ASC (Agent Session Control) — local-first human-in-the-loop agent control plane: core, CLI, and adapters",
5
+ "keywords": [
6
+ "agent",
7
+ "control-plane",
8
+ "human-in-the-loop",
9
+ "claude-code",
10
+ "local-first",
11
+ "session"
12
+ ],
13
+ "homepage": "https://github.com/colosair/asc#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/colosair/asc/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/colosair/asc.git",
20
+ "directory": "packages/runtime"
21
+ },
22
+ "author": "colosair (https://github.com/colosair)",
23
+ "type": "module",
24
+ "bin": {
25
+ "asc": "./dist/cli/asc.js"
26
+ },
27
+ "main": "./dist/cli/asc.js",
28
+ "types": "./dist/cli/asc.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/cli/asc.d.ts",
32
+ "default": "./dist/cli/asc.js"
33
+ }
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "README.md"
38
+ ],
39
+ "engines": {
40
+ "node": ">=24"
41
+ },
42
+ "scripts": {
43
+ "build": "node scripts/build.mjs",
44
+ "prepack": "node scripts/build.mjs",
45
+ "test": "node --test \"tests/*.test.ts\"",
46
+ "dist:smoke": "node scripts/dist-smoke.mjs"
47
+ },
48
+ "dependencies": {
49
+ "zod": "^3.25.76"
50
+ },
51
+ "license": "ISC",
52
+ "publishConfig": {
53
+ "access": "public"
54
+ }
55
+ }