@asc-agent/runtime 0.5.2 → 0.5.4

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.2
10
+ npm install -g @asc-agent/runtime@0.5.4
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.js CHANGED
@@ -929,7 +929,11 @@ async function attachLocalWorkspace(projectRoot, git, declaredWorkspace) {
929
929
  const home = ascHome();
930
930
  const index = await readIndex(home);
931
931
  const existing = lookupLocator(index, projectRoot);
932
- if (existing && !declaredWorkspace) {
932
+ // **자리만 있고 workspace 가 없으면 등록된 것이 아니다.** 이 상태에서 "이미 등록됨" 이라고
933
+ // 답하면 붙기는 성공하는데 기계 전체 화면에는 끝내 나타나지 않는다 — 등록된 서비스가
934
+ // 그 workspace 를 영영 돌지 않는다. 색인이 부분적으로 지워진 자리에서 실제로 그랬다.
935
+ const orphaned = existing !== null && index.workspaces[existing.workspaceId] === undefined;
936
+ if (existing && !orphaned && !declaredWorkspace) {
933
937
  console.log(`Already registered workspace: ${existing.workspaceId}`);
934
938
  return existing.root;
935
939
  }
@@ -961,8 +965,11 @@ async function attachLocalWorkspace(projectRoot, git, declaredWorkspace) {
961
965
  console.log(`같은 프로젝트라면: asc init --profile <id> --workspace ${hits[0].workspace.workspaceId}` +
962
966
  (hits.length > 1 ? ' (후보 중 하나를 골라라)' : ''));
963
967
  }
964
- const workspaceId = newWorkspaceId();
968
+ // 상태가 남아 있으면 그 id 로 되돌린다 — 새 id 를 주면 세션·증거가 있는 자리가 고아로 남는다.
969
+ const workspaceId = orphaned && existing ? existing.workspaceId : newWorkspaceId();
965
970
  const root = join(home, 'workspaces', workspaceId);
971
+ if (orphaned)
972
+ console.log(`This location pointed at ${workspaceId}, which the index no longer lists — registering it again.`);
966
973
  await writeIndex(home, register(index, {
967
974
  workspaceId,
968
975
  root,
@@ -1555,6 +1562,7 @@ async function detectSetupState(values, entry) {
1555
1562
  const attachedProfile = ascRoot ? await lockedProfileId(ascRoot) : undefined;
1556
1563
  // 이번 계획이 쓸 Profile 하나 — 그것의 결합 선언이 비어 있을 때만 제안을 관측한다.
1557
1564
  const targetProfile = values.profile ?? attachedProfile ?? adoptable.adoptable?.id;
1565
+ const stable = entry === 'bootstrap' ? await detectStableInstall(nodeProcessRunner) : undefined;
1558
1566
  return {
1559
1567
  entry,
1560
1568
  projectRoot,
@@ -1573,11 +1581,11 @@ async function detectSetupState(values, entry) {
1573
1581
  host: [{ id: 'claude', status: hostReport.status }],
1574
1582
  // Profile 이 작업 도구를 선언했으면 그 준비 상태까지 본다 (설계 §9.3).
1575
1583
  ...(await workBindingState(ascRoot, projectRoot)),
1576
- // 이 기계의 지속 등록. **별도 onboarding 을 만들지 않는다** — 같은 계획에 함께 든다.
1577
- ...(await persistentRuntimeState(values)),
1578
1584
  // **bootstrap으로 들어왔을 때만 본다.** 설치된 runtime이 자기를 다시 설치할 이유가
1579
1585
  // 없고, 그 축을 안 그리면 plan은 설치된 `asc` 를 전제하지도 않는다 (C-14 §3.4).
1580
- ...(entry === 'bootstrap' ? { stableRuntime: await detectStableInstall(nodeProcessRunner) } : {}),
1586
+ ...(stable ? { stableRuntime: stable } : {}),
1587
+ // 이 기계의 지속 등록. **별도 onboarding 을 만들지 않는다** — 같은 계획에 함께 든다.
1588
+ ...(await persistentRuntimeState(values, Boolean(stable && stable.status !== 'CURRENT'))),
1581
1589
  };
1582
1590
  }
1583
1591
  /**
@@ -1604,7 +1612,7 @@ function runningFromInstalledPackage() {
1604
1612
  function serviceRegistrationAllowed() {
1605
1613
  if (process.env.ASC_SERVICE === 'off')
1606
1614
  return false;
1607
- return runningFromInstalledPackage();
1615
+ return true;
1608
1616
  }
1609
1617
  /**
1610
1618
  * 이 기계에 ASC runtime 이 등록돼 있는가 (설계 §6, Gate 7).
@@ -1612,7 +1620,7 @@ function serviceRegistrationAllowed() {
1612
1620
  * 물어볼 수 없으면 이 축을 그리지 않는다 — 모르는 것을 "해야 한다"로 적으면 설치되지
1613
1621
  * 않은 기계에서 setup 이 영영 끝나지 않는다.
1614
1622
  */
1615
- async function persistentRuntimeState(values) {
1623
+ async function persistentRuntimeState(values, installing) {
1616
1624
  if (!serviceRegistrationAllowed())
1617
1625
  return {};
1618
1626
  const adapter = serviceAdapter();
@@ -1620,10 +1628,19 @@ async function persistentRuntimeState(values) {
1620
1628
  return {};
1621
1629
  // 등록물이 가리킬 자리가 없으면 이 축을 그리지 않는다 — 깨진 등록을 남기느니 등록하지
1622
1630
  // 않고 그 사실을 말한다 (P0 F1).
1631
+ //
1632
+ // **이번 계획이 그 자리를 만든다면 지금 없는 것은 근거가 아니다.** 첫 설치는 npx 로
1633
+ // 들어와 전역 runtime 을 놓는데, 그 전에 판정하면 "가리킬 것이 없다" 가 되어 등록이
1634
+ // 영영 계획에 들지 않는다 — 사람이 뒤에 명령 하나를 더 쳐야 했던 자리다. 등록 자체는
1635
+ // apply 순서상 맨 마지막이고, 그때 다시 해석한다.
1623
1636
  const runtime = await serviceRuntime();
1624
- if (runtime.kind !== 'STABLE') {
1637
+ if (runtime.kind !== 'STABLE' && !installing) {
1625
1638
  return { persistentRuntime: { action: 'unsupported', adapter: adapter.id, detail: runtime.detail } };
1626
1639
  }
1640
+ if (runtime.kind !== 'STABLE') {
1641
+ // 아직 없다 — 이번에 놓는다. 그러면 등록할 것이 생긴다.
1642
+ return { persistentRuntime: { action: 'install', adapter: adapter.id } };
1643
+ }
1627
1644
  const plan = await planPersistentRuntime(adapter, serviceCommand(serviceInterval(values), runtime)).catch(() => null);
1628
1645
  if (!plan)
1629
1646
  return {};
@@ -3869,7 +3886,9 @@ async function serviceRuntime() {
3869
3886
  const stable = await globalRuntimeEntry();
3870
3887
  const check = await checkNodeRuntime(nodeRuntimeDeps());
3871
3888
  return resolveServiceRuntime({
3872
- runningEntry: fileURLToPath(import.meta.url),
3889
+ // **checkout 은 등록물이 가리킬 자리가 아니다.** 지금 도는 것을 후보로 쓰는 것은 그것이
3890
+ // 설치된 패키지일 때뿐이고, 아니면 전역 설치본만 남는다 — 없으면 등록하지 않는다.
3891
+ runningEntry: runningFromInstalledPackage() ? fileURLToPath(import.meta.url) : '/dev/null/not-installed',
3873
3892
  runningNode: process.execPath,
3874
3893
  runningNodeVersion: process.version,
3875
3894
  ...(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.2";
5
- export declare const RUNTIME_SPEC = "@asc-agent/runtime@0.5.2";
6
- export declare const BOOTSTRAP_SPEC = "@asc-agent/bootstrap@0.5.2";
4
+ export declare const RELEASE_VERSION = "0.5.4";
5
+ export declare const RUNTIME_SPEC = "@asc-agent/runtime@0.5.4";
6
+ export declare const BOOTSTRAP_SPEC = "@asc-agent/bootstrap@0.5.4";
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.2';
12
+ export const RELEASE_VERSION = '0.5.4';
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.2",
3
+ "version": "0.5.4",
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",