@asc-agent/runtime 0.5.1 → 0.5.3

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/README.md CHANGED
@@ -7,7 +7,7 @@ proceed-by-default, escalation, audit, the external-write guard, host integratio
7
7
  here.
8
8
 
9
9
  ```bash
10
- npm install -g @asc-agent/runtime@0.5.1
10
+ npm install -g @asc-agent/runtime@0.5.3
11
11
  ```
12
12
 
13
13
  npm owns the executable link (on Windows, npm's own `asc.cmd`). This package never edits
package/dist/cli/asc.d.ts CHANGED
@@ -12,4 +12,6 @@ export type AscEntry = 'runtime' | 'bootstrap';
12
12
  * 사용자가 실행하는 명령이 된다 (0.2.0 회차의 skill.ts가 그랬다).
13
13
  */
14
14
  export { BOOTSTRAP_SPEC } from '../core/distribution/release.ts';
15
+ /** 재실행을 가로질러 진입점을 나르는 자리. 값은 `bootstrap` 하나뿐이다. */
16
+ export declare const ENTRY_ENV = "ASC_ENTRY";
15
17
  export declare function runAscCommand(argv: string[], entry?: AscEntry): Promise<number>;
package/dist/cli/asc.js CHANGED
@@ -515,7 +515,12 @@ function reportNodeRuntime(check, asJson) {
515
515
  for (const action of actions)
516
516
  console.error(` ${action.node.version} at ${action.node.path}\n ${action.display}`);
517
517
  }
518
+ /** 재실행을 가로질러 진입점을 나르는 자리. 값은 `bootstrap` 하나뿐이다. */
519
+ export const ENTRY_ENV = 'ASC_ENTRY';
518
520
  export async function runAscCommand(argv, entry = 'runtime') {
521
+ // 호환 Node 로 다시 실행된 프로세스는 자기가 어느 문으로 들어왔는지 argv 로는 알 수 없다.
522
+ const inherited = process.env[ENTRY_ENV] === 'bootstrap' ? 'bootstrap' : undefined;
523
+ entry = inherited ?? entry;
519
524
  let parsed;
520
525
  try {
521
526
  parsed = parseArgsOrThrow(argv);
@@ -675,7 +680,11 @@ async function runParsedCommand(values, positionals, entry, argv) {
675
680
  if (!runnable.ok) {
676
681
  // 후보를 이미 찾았으면 처방 대신 실행한다 — 같은 명령, 같은 argv, 호환 Node (A6).
677
682
  const reexec = reexecWithCandidate(runnable, argv, {
678
- env: process.env,
683
+ // **어느 문으로 들어왔는지가 재실행을 넘어가야 한다.** 이것이 없으면 bootstrap 으로
684
+ // 시작한 첫 설치가 재실행 뒤 자기를 설치된 runtime 이라고 말하고, 그러면 stable
685
+ // runtime 설치도 기계 등록도 계획에 들지 않는다 — 기본 Node 가 하한보다 낮은 기계에서
686
+ // 첫 설치가 조용히 절반만 끝나던 자리다.
687
+ env: { ...process.env, [ENTRY_ENV]: entry },
679
688
  entry: fileURLToPath(import.meta.url),
680
689
  spawn: (path, args, env) => {
681
690
  const child = spawnSync(path, args, { stdio: 'inherit', env: env });
@@ -1546,6 +1555,7 @@ async function detectSetupState(values, entry) {
1546
1555
  const attachedProfile = ascRoot ? await lockedProfileId(ascRoot) : undefined;
1547
1556
  // 이번 계획이 쓸 Profile 하나 — 그것의 결합 선언이 비어 있을 때만 제안을 관측한다.
1548
1557
  const targetProfile = values.profile ?? attachedProfile ?? adoptable.adoptable?.id;
1558
+ const stable = entry === 'bootstrap' ? await detectStableInstall(nodeProcessRunner) : undefined;
1549
1559
  return {
1550
1560
  entry,
1551
1561
  projectRoot,
@@ -1564,11 +1574,11 @@ async function detectSetupState(values, entry) {
1564
1574
  host: [{ id: 'claude', status: hostReport.status }],
1565
1575
  // Profile 이 작업 도구를 선언했으면 그 준비 상태까지 본다 (설계 §9.3).
1566
1576
  ...(await workBindingState(ascRoot, projectRoot)),
1567
- // 이 기계의 지속 등록. **별도 onboarding 을 만들지 않는다** — 같은 계획에 함께 든다.
1568
- ...(await persistentRuntimeState(values)),
1569
1577
  // **bootstrap으로 들어왔을 때만 본다.** 설치된 runtime이 자기를 다시 설치할 이유가
1570
1578
  // 없고, 그 축을 안 그리면 plan은 설치된 `asc` 를 전제하지도 않는다 (C-14 §3.4).
1571
- ...(entry === 'bootstrap' ? { stableRuntime: await detectStableInstall(nodeProcessRunner) } : {}),
1579
+ ...(stable ? { stableRuntime: stable } : {}),
1580
+ // 이 기계의 지속 등록. **별도 onboarding 을 만들지 않는다** — 같은 계획에 함께 든다.
1581
+ ...(await persistentRuntimeState(values, Boolean(stable && stable.status !== 'CURRENT'))),
1572
1582
  };
1573
1583
  }
1574
1584
  /**
@@ -1595,7 +1605,7 @@ function runningFromInstalledPackage() {
1595
1605
  function serviceRegistrationAllowed() {
1596
1606
  if (process.env.ASC_SERVICE === 'off')
1597
1607
  return false;
1598
- return runningFromInstalledPackage();
1608
+ return true;
1599
1609
  }
1600
1610
  /**
1601
1611
  * 이 기계에 ASC runtime 이 등록돼 있는가 (설계 §6, Gate 7).
@@ -1603,7 +1613,7 @@ function serviceRegistrationAllowed() {
1603
1613
  * 물어볼 수 없으면 이 축을 그리지 않는다 — 모르는 것을 "해야 한다"로 적으면 설치되지
1604
1614
  * 않은 기계에서 setup 이 영영 끝나지 않는다.
1605
1615
  */
1606
- async function persistentRuntimeState(values) {
1616
+ async function persistentRuntimeState(values, installing) {
1607
1617
  if (!serviceRegistrationAllowed())
1608
1618
  return {};
1609
1619
  const adapter = serviceAdapter();
@@ -1611,10 +1621,19 @@ async function persistentRuntimeState(values) {
1611
1621
  return {};
1612
1622
  // 등록물이 가리킬 자리가 없으면 이 축을 그리지 않는다 — 깨진 등록을 남기느니 등록하지
1613
1623
  // 않고 그 사실을 말한다 (P0 F1).
1624
+ //
1625
+ // **이번 계획이 그 자리를 만든다면 지금 없는 것은 근거가 아니다.** 첫 설치는 npx 로
1626
+ // 들어와 전역 runtime 을 놓는데, 그 전에 판정하면 "가리킬 것이 없다" 가 되어 등록이
1627
+ // 영영 계획에 들지 않는다 — 사람이 뒤에 명령 하나를 더 쳐야 했던 자리다. 등록 자체는
1628
+ // apply 순서상 맨 마지막이고, 그때 다시 해석한다.
1614
1629
  const runtime = await serviceRuntime();
1615
- if (runtime.kind !== 'STABLE') {
1630
+ if (runtime.kind !== 'STABLE' && !installing) {
1616
1631
  return { persistentRuntime: { action: 'unsupported', adapter: adapter.id, detail: runtime.detail } };
1617
1632
  }
1633
+ if (runtime.kind !== 'STABLE') {
1634
+ // 아직 없다 — 이번에 놓는다. 그러면 등록할 것이 생긴다.
1635
+ return { persistentRuntime: { action: 'install', adapter: adapter.id } };
1636
+ }
1618
1637
  const plan = await planPersistentRuntime(adapter, serviceCommand(serviceInterval(values), runtime)).catch(() => null);
1619
1638
  if (!plan)
1620
1639
  return {};
@@ -3860,7 +3879,9 @@ async function serviceRuntime() {
3860
3879
  const stable = await globalRuntimeEntry();
3861
3880
  const check = await checkNodeRuntime(nodeRuntimeDeps());
3862
3881
  return resolveServiceRuntime({
3863
- runningEntry: fileURLToPath(import.meta.url),
3882
+ // **checkout 은 등록물이 가리킬 자리가 아니다.** 지금 도는 것을 후보로 쓰는 것은 그것이
3883
+ // 설치된 패키지일 때뿐이고, 아니면 전역 설치본만 남는다 — 없으면 등록하지 않는다.
3884
+ runningEntry: runningFromInstalledPackage() ? fileURLToPath(import.meta.url) : '/dev/null/not-installed',
3864
3885
  runningNode: process.execPath,
3865
3886
  runningNodeVersion: process.version,
3866
3887
  ...(stable ? { stableEntry: stable } : {}),
@@ -1,9 +1,9 @@
1
1
  export declare const RUNTIME_PACKAGE = "@asc-agent/runtime";
2
2
  export declare const BOOTSTRAP_PACKAGE = "@asc-agent/bootstrap";
3
3
  /** runtime과 bootstrap은 초기 release에서 lockstep이다. */
4
- export declare const RELEASE_VERSION = "0.5.1";
5
- export declare const RUNTIME_SPEC = "@asc-agent/runtime@0.5.1";
6
- export declare const BOOTSTRAP_SPEC = "@asc-agent/bootstrap@0.5.1";
4
+ export declare const RELEASE_VERSION = "0.5.3";
5
+ export declare const RUNTIME_SPEC = "@asc-agent/runtime@0.5.3";
6
+ export declare const BOOTSTRAP_SPEC = "@asc-agent/bootstrap@0.5.3";
7
7
  /**
8
8
  * 아직 설치되지 않은 machine에서 그대로 실행되는 형태 (C-14 §3.4).
9
9
  *
@@ -9,7 +9,7 @@
9
9
  export const RUNTIME_PACKAGE = '@asc-agent/runtime';
10
10
  export const BOOTSTRAP_PACKAGE = '@asc-agent/bootstrap';
11
11
  /** runtime과 bootstrap은 초기 release에서 lockstep이다. */
12
- export const RELEASE_VERSION = '0.5.1';
12
+ export const RELEASE_VERSION = '0.5.3';
13
13
  export const RUNTIME_SPEC = `${RUNTIME_PACKAGE}@${RELEASE_VERSION}`;
14
14
  export const BOOTSTRAP_SPEC = `${BOOTSTRAP_PACKAGE}@${RELEASE_VERSION}`;
15
15
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asc-agent/runtime",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "ASC (Agent Session Control) \u2014 local-first human-in-the-loop agent control plane: core, CLI, and adapters",
5
5
  "keywords": [
6
6
  "agent",